Seite 1 von 2

QTableView mit verschiedenen editierbaren Widgets

Verfasst: 18. März 2008 00:05
von pfotenpo
Hallo,

ich habe folgendes Problem:
ich will eine Tabelle erstellen mit einer Anzahl an Zeilen die sich aus einem eingelesenen XML Dokument bestimmt. Die Tabelle hat nur 3 Spalten. In der 1. Spalte sollen nur QStrings angezeigt werden (nicht editierbar). In der 2. Spalte sollten auch nur QStrings stehen (nicht editierbar). In der 3. Spalte nun das eigentliche Problem:

Je nachdem welches Wort in der 2. Spalte steht (dort steht sowas wie: "Integer", "String",...) soll in der 3. Spalte ein Feld sein, dass editierbar mit einer QComboBox oder einer QSpinBox ist. Ich brauch wirklich nur diese 2 verschieden Widgets eigentlich.

Wie könnte man so etwas realisieren?? Man muss dazu sagen, dass sich die Inhalte der QSpinBoxen und der QComboBoxen auch jeweils noch unterschieden (soll alles aus einer XML Datei eingelesen werden). Das "Qt SpinBox Delegate-Beispiel" geht schon in die richtige Richtung. Aber ich will ja nur ganz bestimmte Zellen editierbar machen und dann halt jeweils mit unterschiedlichen Widgets die auch jeweils unterschiedliche Inhalte haben sollen.

Im Grunde genommen suche ich HAARGENAU sowas wie im Qt Designer das "Eigenschaften-" oder "Property-" Window. Das ist so aufgebaut wie ich mir das wünsche.

Bin für jede Hilfe dankbar.
Stefan

Verfasst: 18. März 2008 09:04
von upsala
Editierbar wird eine Zelle über das Editable-Flag. Und das SpinBox-Example kann man so erweitern, daß je nach Inhalt andere Widgets ausgegeben werden.

Verfasst: 18. März 2008 11:38
von pfotenpo
ok. ich nehme an die setFlags()-Methode muss ich beim QStandardItem verwenden. Bewirkt denn die setEditable()-Methode dasselbe als wenn ich das editable-Flag des Items setzen würde?

Gehe ich richtig davon aus, dass ich eine QItemEditorFactory einsetzen muss, um das zu erreichen was ich will? Also verschiedene Editor-Widgets (kontextabhängig) zu nutzen?

Verfasst: 18. März 2008 12:21
von upsala
Nein, die QItemEditorFactory brauchst du nicht. (Hat die schon mal jemand benutzt?)

In der createEditor-Methode kannst du doch anhand deiner Daten entscheiden welches Widget du erstellen willst. Und in setEditorData und setModelData mußt du halt dann richtig auf dieses Widget zugreifen...

Verfasst: 18. März 2008 12:55
von pfotenpo
ok....und wenn ich eine Zelle in meiner TableView doppelt anklicke (oder einfach) dann soll sich ja der passende Editor öffnen. Das Öffnen des Editors geschieht automatisch über SIGNAL/SLOT Mechanismen? Hab dazu kein passendes SIGNAL finden können. Und aus dem SpinBox-Beispiel ist der Vorgang des Öffnens eines Editors bei Doppelklick nicht ersichtlich.

Kann ich die createEditor-Methode des QItemDelegates überladen um eigene zusätzliche Parameter für die Methode zu liefern? Also zum Beispiel Minimal- und Maximal-Wert für die zu öffnende SpinBox?

Verfasst: 18. März 2008 13:03
von pfotenpo
ach und WIE kann ich denn innerhalb der createEditor()-Methode des QItemDelegates entscheiden welches Widget ich erstellen will???

Danke.

Verfasst: 18. März 2008 13:56
von RHBaum
gar ned

an deinem ItemView ermitteln die Funktionen das delegate

QAbstractItemDelegate * itemDelegate () const
QAbstractItemDelegate * itemDelegate ( const QModelIndex & index ) const
QAbstractItemDelegate * itemDelegateForColumn ( int column ) const
QAbstractItemDelegate * itemDelegateForRow ( int row ) const
welche du ueberschreiben kannst

Du musst sicherstellen, das dein delegate der richtige Typ ist, und somit erzeigt die create methode das richtige Widget liefert...

Tip:
du kannst ne benutzerdefinierte Rolle in deinem ItemModel Anlegen (fuer data funktion) ... wo du nen int/enum fuer den typ deines Delegates hinterlegen kannst.
Der rueckgabewert kann aber auch was komplexeres sein, also wo nicht nur der typ, sondern auch min/max werte etx drinne stehen ....
So brauchst du keine extra spalte(n) nur fuer die "Art" des editors ....

Ciao ....

Verfasst: 18. März 2008 16:31
von upsala
ach und WIE kann ich denn innerhalb der createEditor()-Methode des QItemDelegates entscheiden welches Widget ich erstellen will???
Das mußt du anhand deiner Daten selbst entscheiden. Du weist doch jetzt auch, daß du für Texte ein LineEdit willst und für Integer eine SpinBox...

Verfasst: 18. März 2008 19:08
von pfotenpo
mh...so ganz klar ist mir das alles nicht :roll:
ich hab erstmal ein neues QStandardItemModel erzeugt und meine QTableView mit diesem Model gefüttert.
Das klappt erstmal ganz gut und sieht schon fast schick aus.
2 Probleme habe ich jetzt dennoch.

(1) Ich muss meine Delegates mit Werten versorgen, die ich aus einer XML Datei ausgelesen habe (d.h. also jede SpinBox könnte durchaus andere Werte habe, ebenso die ComboBoxen).

(2) Wie bekomme ich das hin, dass die 3 Spalten des Models genau die Breite des TableViews ausfüllen?!? Und zwar auch dann wenn ich meine TableView mit der Maus vergrößere. Die Breite der Spalten soll dann im Prinzip mitwachsen.

Danke für euer Antworten bisher. Das hilft weiter. Ist nicht immer ganz einfach so als "Nicht-Programmierer" so ein Programm zu basteln für die Uni...

Verfasst: 18. März 2008 23:45
von pfotenpo
okay. mein eines Problem mit der flexiblen Spaltenbreite habe ich hinbekommen.

Folgender Code tut genau das was ich wollte:

Code: Alles auswählen

myTableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
:)

Verfasst: 19. März 2008 04:45
von franzf
Und dein anderes Problem versteh ich nicht. Denn eigentlich bekommt der Delegate seine Daten automatisch. Nämlich genau die Daten, welche in der Zelle stehen, für die der Delegate geöffnet wurde.

Oder hab ich deine Frage komplett falsch verstanden?

Verfasst: 19. März 2008 11:06
von pfotenpo
na okay...sagen wir mal der Delegate bekommt seine Daten automatisch. Ich müsste in dem Moment dann prüfen ob die erhaltenen Daten einem QString, einem Bool oder einem Int entsprechen oder wie? Das Ding ist halt, das grundsätzlich erstmal alle Werte in der Tabelle aus ner XML Datei ausgelesen werden und von daher grundsätzlich erstmal als QString interpretiert werden.
D.h. selbst wenn in einem Feld eine "100" steht, und ich doppelt draufklickt öffnet sich ein QLineEdit.

Verfasst: 19. März 2008 11:14
von franzf
In dem Fall solltest du unbedingt beim Einlesen deines XML die Daten in den korrekten Typ konvertieren.
Ich nehme an du weißt in welchem Feld in dem XML du welchen Typ erwartest (und hoffe auch das ist dann konsistent im ganzen XML-File), dann brauchst du dir nur noch die Doku anschauen (Anlaufstellen sind QString und QVariant) und entsprechend konvertieren.

Grüße
Franz

Verfasst: 19. März 2008 12:21
von pfotenpo
ja. das wär ne Idee. Danke!
Dann würde bei Doppelklick auf "100" zumindest eine SpinBox erscheinen. Stimmt. Dennoch komme ich um eigene Delegates denke ich nicht herum, weil ich ja jetzt jeweils noch Minimal und MaximalWert für die SpinBox brauche. Und die stehen auch im XML File (und sind oder können obendrein für jedes Integer Feld anders sein). Ich muss die also aus dem XML File auslesen und an das Delegate als Parameter übergeben. *Angst* :oops:
Ne, aber das wird schon denk ich.
Ich danke euch auf jeden Fall schonmal.

Verfasst: 19. März 2008 12:24
von upsala
Dafür kann man die User-Roles verwenden. Ebenso kann man eine User-Role verwenden, um zu entscheiden welches Widget du verwenden willst, denn das steht anscheinend auch in deinem XML-Element.