Hallo,
wenn ich in einer QListView einen anderen Eintrag auswähle und damit das "clicked"-Signal sende, wie komme ich an den Index des Eintrags im empfangenen Slot (z.B. im einfachsten Fall, um den Taxt eines Labels zu ändern, etc...)?
Stehe irgendwie auf dem Schlauch gerade.
Danke und Gruß.
QListView signals
Das steht doch in der Doku: https://doc.qt.io/qt-6/qabstractitemview.html#clicked - du bekommst den Index.
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
Ja, danke. Ich habe aber das Problem, dass ich an den Eintrag, den ich ausgewählt habe, nicht heran komme. D.h. dahinter liegt ja mein model, welches ist auch mit .model erreiche. Jedoch kann ich keinerlei funktionen darauf aufrufen. D.h. example_list.model.some_function() ist nicht möglich. Wie komme ich also tatsächlich an die Listeneinträge dran? Finde in der Doku auch nichts bzgl. item(index) oder sonstwas. Auch in den vererbenden Klassen nicht.__deets__ hat geschrieben: ↑Freitag 19. April 2024, 10:47 Das steht doch in der Doku: https://doc.qt.io/qt-6/qabstractitemview.html#clicked - du bekommst den Index.
- __blackjack__
- User
- Beiträge: 13191
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@mechanicalStore: Du suchst wohl die `data()`-Methode.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
Hallo __blackjack___,__blackjack__ hat geschrieben: ↑Freitag 19. April 2024, 13:22 @mechanicalStore: Du suchst wohl die `data()`-Methode.
ja, die habe ich auch schon gesucht. Und nicht erreichbar über die QListView.model, sondern nur über das model selbst, das hatte ich übersehen. Funktioniert jetzt. Besten Dank.
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
Hallo,
jetzt habe ich doch noch ein Problem. Da im u.g. (stark gekürzten) Beispiel id der primary key ist, kann es natürlich beliebig viele internal_number geben. Durch die Auswahl in der QListView gelange ich über index und die data methode wiederum an die id. Sind aber mehrere gleiche Einträge drin, bekomme ich wegen .first() immer die erst gefundene id zurück. Gibt es einen Weg, über den Index der QListView auch direkt wieder an die id zu kommen?
jetzt habe ich doch noch ein Problem. Da im u.g. (stark gekürzten) Beispiel id der primary key ist, kann es natürlich beliebig viele internal_number geben. Durch die Auswahl in der QListView gelange ich über index und die data methode wiederum an die id. Sind aber mehrere gleiche Einträge drin, bekomme ich wegen .first() immer die erst gefundene id zurück. Gibt es einen Weg, über den Index der QListView auch direkt wieder an die id zu kommen?
Code: Alles auswählen
#sqlmodel
class Part(Base):
__tablename__ = "part_basedata"
id: Mapped[int] = mapped_column(primary_key=True)
measurings: Mapped[List["Measuring"]] = relationship(back_populates="part")
internal_number: Mapped[int]
...
@classmethod
def get_all_internal_numbers(cls, session) -> int:
return session.execute(select(cls.internal_number)).scalars().all()
@classmethod
def get_id_by_internal_number(cls, session, internal_number) -> int:
return session.scalars(select(cls.id).where(cls.internal_number == internal_number)).first()
#gridmodel
class PartListModel(QAbstractListModel):
def __init__(self, session):
super().__init__()
self.session = session
self.part_data = Part.get_all_internal_numbers(self.session)
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.ItemDataRole.EditRole:
return self.part_data[index.row()]
#gridview
class MainWindow(QMainWindow):
def __init__(self, session):
self.parts_view = QListView()
self.parts_model = PartListModel(self.session)
self.parts_view.setModel(self.parts_model)
...
self.parts_view.clicked.connect(self.set_part_description_labels)
...
@Slot()
def set_part_description_labels(self, index):
internal_number = self.parts_model.data(index, Qt.ItemDataRole.DisplayRole)
part_id = Part.get_id_by_internal_number(self.session, internal_number)
...
self.part_internal_number_description.setText(f'Part-Number: = {str(internal_number)}')
...
print(part_id)
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
Jemand eine Idee dazu?...Gibt es einen Weg, über den Index der QListView auch direkt wieder an die id zu kommen?
- __blackjack__
- User
- Beiträge: 13191
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@mechanicalStore: Ich würde da einfach beides von der Datenbank abfragen. Also eigentlich würde ich sogar einfach ganze `Part`-Objekte abfragen. Denn wozu ein ORM wenn man dann doch immer nur einzelne Werte abfragt und nicht die Objekte. Vielleicht würde es sogar Sinn machen ein Model zu erstellen das mehr als nur diese eine Spalte der Datenbank liefert. Man kann bei QListView ja festlegen welche Spalte verwendet werden soll.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
@__blackjack__: Es werden quasi die Autofilter einer Excel Liste nachgebildet (natürlich nur ,was die Auswahl betrifft). In Part gibt es Einträge, zu jedem dieser Einträge gibt es in Measuring eine Teilmenge. Ebenso gibt es zu jedem Eintrag in Measuring eine Teilmenge in MeasuringPiece. Also quasi surjektive Abbildungen. Wähle ich aus Part einen Eintrag aus, soll die entsprechende Teilmenge in Measuring (d.h. ebenfalls wieder eine QListView) aufgelistet werden (und vice versa nach Unten, wieder QListView). Da Part auch gleiche Einträge haben kann, wird eben der "Rückweg", die id anhand des (doppelt oder mehrfachen) Eintrags zu finden, nicht mehr möglich.
Du meinst also, dass für jede der 3 Tabellen jeweils alles abgefragt und nur die entsprechende Spalte angezeigt wird?!
Du meinst also, dass für jede der 3 Tabellen jeweils alles abgefragt und nur die entsprechende Spalte angezeigt wird?!
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
@__blackjack__:
stehe irgendwie auf dem Schlauch. Wie Du geschrieben hast, ist es besser, das ganze Object abzufragen, und in der QListView nur die entsprechende Spalte anzuzeigen. Das funktioniert auch, aber wie komme ich wieder an das Object selbst dran? Das muss doch über den Index gehen, aber ich habe hier offenbar nicht die Struktur, die ich brauche?!
Gekürztes Beispiel:
Ausgabe:
stehe irgendwie auf dem Schlauch. Wie Du geschrieben hast, ist es besser, das ganze Object abzufragen, und in der QListView nur die entsprechende Spalte anzuzeigen. Das funktioniert auch, aber wie komme ich wieder an das Object selbst dran? Das muss doch über den Index gehen, aber ich habe hier offenbar nicht die Struktur, die ich brauche?!
Gekürztes Beispiel:
Code: Alles auswählen
# sqlqlchemy
class Part(Base):
__tablename__ = "part_basedata"
id: Mapped[int] = mapped_column(primary_key=True)
measurings: Mapped[List["Measuring"]] = relationship(back_populates="part")
internal_number: Mapped[int]
internal_name: Mapped[Optional[str]]
customer_number: Mapped[Optional[str]]
customer_name: Mapped[Optional[str]]
...
@classmethod
def get_all_objects(cls, session):
return session.execute(select(cls)).scalars().all()
# qt model
class PartListModel(QAbstractListModel):
def __init__(self, session):
super().__init__()
self.session = session
self.part_data = Part.get_all_objects(self.session)
...
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.ItemDataRole.EditRole:
return self.part_data[index.row()].internal_number
# qt view
...
self.parts_view = QListView()
self.parts_model = PartListModel(self.session)
self.parts_view.setModel(self.parts_model)
...
self.parts_view.clicked.connect(self.set_part_description_labels)
...
@Slot()
def set_part_description_labels(self, index):
internal_number = self.parts_model.data(index, Qt.ItemDataRole.DisplayRole)
print(type(internal_number))
print(internal_number)
print(type(self.parts_model.data))
print(self.parts_model.data)
print(self.parts_model.data[index.row()])
....
Code: Alles auswählen
<class 'int'>
80757
<class 'method'>
<bound method PartListModel.data of <gridmodel.PartListModel(0x61d86b62c240) at 0x72c01b2a9900>>
Traceback (most recent call last):
File "/home/******/develop/git/measuring/gridview.py", line 83, in set_part_description_labels
print(self.parts_model.data[index.row()])
~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
TypeError: 'method' object is not subscriptable
- __blackjack__
- User
- Beiträge: 13191
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
`data` ist eine Methode und [ ] sind die falschen Klammern für einen Methodenaufruf.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
Ja, und damit komme ich dann zu:
Ausgabe:
Womit ich dann wieder hier bin:
Was mir nur den Integerwert der Auswahl zurück gibt. Daher war ja meine Frage, wie ich wieder an das eigentliche Object komme, denn der Weg scheint ja komplett ins Leere zu führen.
Code: Alles auswählen
print(self.parts_model.data())
Code: Alles auswählen
print(self.parts_model.data())
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: PartListModel.data() missing 2 required positional arguments: 'index' and 'role'
Code: Alles auswählen
internal_number = self.parts_model.data(index, Qt.ItemDataRole.DisplayRole)
-
- User
- Beiträge: 137
- Registriert: Dienstag 29. Dezember 2009, 00:09
Hallo Zusammen,
habe es jetzt mit einem Workaround lösen können...
Ist es legitim, nicht die data() methode des models zu benutzen (s. auskommentierte Zeile) und stattdessen das model sozusagen nochmal zuzuweisen (an object_choice)? Funktioniert so zwar, kommt mir aber immer noch umständlich vor. Der index der QLIstView lässt sich über die data() methode irgendwie nicht verwenden.
(Einrückung kommt am Schluss nicht richtig rüber)
habe es jetzt mit einem Workaround lösen können...
Code: Alles auswählen
class PartListModel(QAbstractListModel):
def __init__(self, session):
super().__init__()
self.session = session
self._part_data = Part.get_all_objects(self.session)
...
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.ItemDataRole.EditRole:
return self._part_data[index.row()].internal_number
@property
def datamodel(self):
return self._part_data
class MainWindow(QMainWindow):
def __init__(self, session):
super().__init__(windowTitle = "Main Window")
self.resize(QSize(1500, 800))
self.session = session
self.setStatusBar(QStatusBar(self))
self.parts_view = QListView()
self.parts_model = PartListModel(self.session)
self.parts_view.setModel(self.parts_model)
.....
self.parts_view.clicked.connect(self.set_part_description_labels)
...
@Slot()
def set_part_description_labels(self, index):
# internal_number = self.parts_model.data(index, Qt.ItemDataRole.DisplayRole)
object_choice = self.parts_model.datamodel
part_id = object_choice[index.row()].id
internal_number = object_choice[index.row()].internal_number
internal_name = object_choice[index.row()].internal_name
customer_number = object_choice[index.row()].customer_number
customer_name = object_choice[index.row()].customer_name
(Einrückung kommt am Schluss nicht richtig rüber)