Qtableview+QAbstractTableModel - Reihe auswählen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Hallo, wie man aus dem Betreff schon ablesen kann, habe ich eine QTableView Tabelle, bei der ich einen Eintrag auswählen will und dann Editiere.
Dabei will ich nicht dass der Eintrag direkt in der Tabelle geändert wird, sondern in einem extra Fenster. Dazu sollte ich also den Inhalt einer Reihe zurückgegeben bekommen, wenn ich per Doppelklick darauf Klicke, damit ich dann mit diesen werten ein neues Fenster öffnen kann.
Statt dem Doppelklick würde es auch gehen, wenn ich einen Button unterhalb der Tabelle platziere und ich beim klicken auf den Button den in der Tabelle markierten Eintrag zurückbekomme.

Ich bin bereits auf dieses Threat gestoßen, weiß aber nicht wie ich es anwenden kann: http://stackoverflow.com/questions/4324 ... qtableview

Liebe grüße
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

hat niemand eine Idee oder habe ich mich vielleicht zu unverständlich ausgedrückt?
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Du musst das doubleClicked-SIGNAL eben mit einer Methode von dir verknüpfen:

Code: Alles auswählen

treeView.doubleClicked.connect(some_function)
Aber das konntest du ja alles schon in dem Thread nachlesen. Wo liegt also das Problem? Vielleicht solltest du dir das hier mal durchlesen: New-style Signal and Slot Support
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Ja, mein Problem ist noch, wie ich den Eintrag, der angeklickt wurde, an meine Funktion weitergeben kann. Wird mir dieser Eintrag irgendwo zurückgegeben?
lunar

@Trubinial Guru: Das Signal liefert Dir ein Objekt vom Typ "QModelIndex", also einen Verweis auf den entsprechenden Eintrag im Modell. An die Daten des Eintrags kommst Du, indem Du die ".data()"-Methode des Modells damit aufrufst (und die richtige Rolle übergibst).

Das steht im Übrigen alles in der Dokumentation, Absatz „Model classes, Basic Concepts, Model indexes“.
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Vielen Dank schonmal für die ersten Erfolge. Ich in der Dokumentation nachgeschaut, doch leider ist mein Englisch nicht perfekt...
Undzwar verstehe ich nicht was der unterschied zwischen "index" und "role" ist und wie ich die bekomme.

Wäre schön wenn ihr mir noch ein wenig Mutterhilfe geben könntet
lunar

Der Index sagt, wo die Daten liegen, und die Rolle beschreibt die Art der Daten, die Du von dieser Stelle holen möchtest (z.B. den angezeigten Text, das angezeigte Symbol, usw.).
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Ahh oki, aber wie bekomme ich diese Parameter denn? Ich muss sie ja irgendwo herbekommen, um die .data methode meiner Klasse aufzurufen? Da steig ich noch nich ganz durch.
LG
lunar

@Trubinial Guru: Nun, den Index bekommst Du doch wohl ganz offensichtlich vom Signal als Argument übergeben, wie man Dir bereits weiter oben erklärt hat. Die Rolle musst Du selbst aus den verfügbaren Werten so wählen, dass Du zu diesem Index das gewünschte Datum erhältst.

In der Dokumentation sind doch Tonnen von Beispielen dazu zu finden. Gut, sie sind in C++, aber das Prinzip sollte doch zumindest klar werden, so schwer ist das doch nicht.
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Seid ihr euch sicher dass das auch mit QtableView funktioniert, weil er scheint bei mir nicht den index zu übergeben. Ich beiß mir da jetzt schon mehrere Stunden die Zähne aus...
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Ja, sind wir. Zeig doch einfach mal was du an Code hast, dann kann man dir vielleicht auch helfen.
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Oki, also mein Verbindung zu der Methode sieht so aus:
self.connect(self.datenbank_auflistung, QtCore.SIGNAL('doubleClicked(QModelIndex)'), self.feedback_web(QModelIndex))
Voń der Methode aus wird die .data Methode meines AbtractTablemodells aufgerufen
def data(self, index, role=QtCore.Qt.DisplayRole):
return QVariant(self.arraydata[index.row()][index.column()])
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also ich würde vor allem mal auf die neue Schreibweise für connects umstellen - das liest sich leichter:

Code: Alles auswählen

self.datenbank_auflistung.doubleClicked.connect(self.feedback_web)
Was sagt Dir denn `index.row()` oder `index.column()` in der `feedback_web`-Methode? Da würde ich mir das mal ausgeben lassen!

Stimmen die Indizes dürfte Deine `data`-Methode oder das `arraydata`-Attribut in Deinem Model Probleme bereiten.

Wieso arbeitest Du eigentlich mit AbstractModel? Prinzipiell ja schon ok, aber tun es die Standard-Models nicht auch bei Dir?

Der Name `datenbank` lässt ja irgend wie erahnen, dass Du da was mit Datenbanken machst. Für relationale DBs bietet Qt bereits fertige Model-Klassen. Evtl. kannst Du diese nehmen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Ahh misst hab vergessen zu schreiben was er überhaupt ausgibt:
return QVariant(self.arraydata[index.row()][index.column()])
TypeError: QModelIndex.row(): first argument of unbound method must have type 'QModelIndex'
Es ist so, dass die Tabelle nur eine nebensächliche Rolle spielt und ich noch relativ in den Anfängen mit Python und Qt bin. Aus dem ersten Blick aus sah es so aus als wäre das AbstractMode leichter als die anderen Modelle.

Auf folgende Zeilen gibt er folgendes aus:

Code: Alles auswählen

        print index
        print stindex.row()

Code: Alles auswählen

<class 'PyQt4.QtCore.QModelIndex'>
<built-in function row>
print index.row()
TypeError: QModelIndex.row(): first argument of unbound method must have type 'QModelIndex'
Oder kann es vielleicht daran liegen, wie ich die .data methode aufrufe? Weil das kommt mir ein wenig komisch vor:

Code: Alles auswählen

print TableModel(list, header, self).data(modelindex, 0)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Trubinial Guru hat geschrieben: Es ist so, dass die Tabelle nur eine nebensächliche Rolle spielt und ich noch relativ in den Anfängen mit Python und Qt bin. Aus dem ersten Blick aus sah es so aus als wäre das AbstractMode leichter als die anderen Modelle.
Naja, bei den anderen Modellen musst Du ja viel weniger implementieren, da die per se schon alles an Basisfunktionalität mitbringen. "Ready to use" quasi.
Trubinial Guru hat geschrieben: Auf folgende Zeilen gibt er folgendes aus:

Code: Alles auswählen

        print index
        print stindex.row()

Code: Alles auswählen

<class 'PyQt4.QtCore.QModelIndex'>
<built-in function row>
print index.row()
TypeError: QModelIndex.row(): first argument of unbound method must have type 'QModelIndex'
Das passt ja schon mal nicht zusammen! `stindex` ist ja ein anderer Name als `index` - ist dahinter dasselbe Objekt? Zudem wird die die `row`-Methode aufgerufen - die Ausgabe erwähnt aber das Funktionsobjekt. Passt auch nicht!
Trubinial Guru hat geschrieben: Oder kann es vielleicht daran liegen, wie ich die .data methode aufrufe? Weil das kommt mir ein wenig komisch vor:

Code: Alles auswählen

print TableModel(list, header, self).data(modelindex, 0)
Der Aufruf sieht krude aus. Oder dient das Anlegen eines neues Objektes nur der Demonstration? Auch hier wäre Original-Code besser, zu dem Du dann sagst, dass sich hinter einem Namen ein `TableModel` befindet. Integer-Konstanten sollte man nicht einfach ohne Namen übergeben! Kann sich alles ändern in Zukunft, dann stehst Du dumm da.

Bastel doch einfach mal ein minimales und lauffähiges Programm und poste das hier (am besten im eingebauten Paste-bin oder auf paste.pocoo.org). So kommen wir nicht weiter... nur mit Fragmenten sieht man schlecht, welches Objekt sich an welcher Stelle hinter welchem Namen befindet. `index` ist innerhalb eines `QAbstractItemModels` eine Methode - evtl. kollidiert da etwas.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Hey, ich war grade dabei ein mini Programm damit zu erstellen, als ich gemerkt habe, dass es plötzlich funktioniert =)
Ich habe mehrere kleine Sachen geändert, kann aber nicht genau sagen woran es lag, vielleicht an der connect Schreibweise.
Nur gibt es noch ein Problem: Anders als im mini-Programm beendet sich mein "großes" Programm nach dem Doppelklick auf eine Zeile und der anschließenden Rückgabe der Daten. Die letzte Meldung im Terminal:
Speicherzugriffsfehler
Habt ihr ne Idee??
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ja. Das sieht danach aus, als würdest Du den `parent`-Parameter an irgend einer Stelle nicht sauber setzen. Tust Du das nicht, so wird das C++-Objekt im Speicher evtl. zu früh gelöscht. Dann kommt es im Qt-Umfeld gerne mal zu diesem Fehler.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Ohje, gibts da irgendeinen Tipp um die betroffene Stelle zu finden, ich hätte keine Ahnung wo ich anfangen soll zu suchen...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Trubinial Guru hat geschrieben:Ohje, gibts da irgendeinen Tipp um die betroffene Stelle zu finden, ich hätte keine Ahnung wo ich anfangen soll zu suchen...
Naja, beim Modell im Zweifel. Die Objekte, die beim Crash eine Rolle spielen eben...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@Trubinial Guru: Woher sollten wir denn wissen, wo Du nach dem Fehler suchen musst?! Wir kennen ja nicht einmal den Quelltext ... und niemand hier kann hellsehen :)

Es wäre also hilfreich, ein Beispiel zu zeigen, dass den Absturz reproduziert (und bitte nur ein Beispiel, nicht den gesamten Quelltext).

Insgesamt hört sich das auch so an, als würdest Du oft einfach so lange am Quelltext rumprobieren, bis es „funktioniert“, programming by accident also. Zumindest schließe ich das aus der Tatsache, dass Du selbst nicht mehr zu wissen scheinst, welche Effekte die von Dir am Quelltext vorgenommenen Änderungen haben. Es wäre für Dich und für uns einfacher, wenn Du strukturierter Vorgehen würdest, und Dir jeweils immer vor der Anpassung des Quelltext überlegst, was Du erreichen möchtest und wie das umzusetzen wäre.
Antworten