QTableView mit verschiedenen editierbaren Widgets

Alles rund um die Programmierung mit Qt
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

QTableView mit verschiedenen editierbaren Widgets

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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.
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag 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?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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...
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag 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?
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag von pfotenpo »

ach und WIE kann ich denn innerhalb der createEditor()-Methode des QItemDelegates entscheiden welches Widget ich erstellen will???

Danke.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag 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 ....
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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...
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag 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...
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag 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);
:)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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?
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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
pfotenpo
Beiträge: 33
Registriert: 17. Februar 2008 15:07

Beitrag 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.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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.
Antworten