Seite 1 von 2

QTreeView und Checkboxen

Verfasst: 19. Mai 2010 15:01
von qrk123
Hallo,

im Moment versuche ich gerade herauszufinden, wie man eine Liste aller QtreeItemWidgets erhält, bei denen die CHeckbox markiert ist.

Erster Versuch war über das signal "itemChanged" des TreeWidgets und sah so aus:
connect( ui.treeWidget, SIGNAL( itemChanged( QTreeWidgetItem* item, int column ) ), SLOT( itemChecked( ) ) );

Allerdings wird itemChecked() nie ausgelöst, egal was man selektiert.

Zweiter Versuch:
Iterieren über alle Items vom TreeWidget. Allerdings scheiter ich hier schon dabei heraus zufinden wie ich alle items ansteuere, wobei die Abfrage dann ob sie selektiert wären wohl kein Problem ist.

Weiß Jemand an wie ich zumindest einen dieser Ansätze durchführen könnte? würde mich freuen.

vielen Dank

Alle Items durchsuchen

Verfasst: 19. Mai 2010 16:17
von stefanborries
Man könnte:
- alle top-level Items durchsuchen (topLevelItemCount + topLevelItem ( int index )).
- Für jedes top-level item geht man die children durch (childCount + child ( int index )). Natürlich muss man auch für jedes child nach weiteren children suchen.
- Bei jedem QTreeWidgetItem untersucht man ob es gecheckt ist.
So bekommt man seine Liste.

Das ist jetzt aber nur so dahin geschrieben. Es gibt sicher performantere Wege.

Verfasst: 19. Mai 2010 16:24
von upsala
Mal davon abgesehen, daß der connect so nie funktionieren kann, geschweige denn kompiliert werden kann.

Verfasst: 19. Mai 2010 16:48
von qrk123
das der connect nicht geht weiß ich auch, würdest du mir zeigen wies richtig wäre?
Es gibt eine spezielle Methode um mittels Koordinaten die items durchzugehen, allerdings braucht man scheinbar einen "Qpointer" wie ich mit dem iteriere ha ich auch noch nicht verstanden. :(

Verfasst: 19. Mai 2010 17:58
von brax
Versuch das connect mal so:

Code: Alles auswählen

connect( ui.treeWidget, SIGNAL( itemChanged( QTreeWidgetItem*, int) ), this, SLOT( itemChecked( ) ) ); 
Oder noch besser, Du änderst Deinen itemChecked() slot, dass er auch noch das Item und die Column bekommt:

Code: Alles auswählen

connect( ui.treeWidget, SIGNAL( itemChanged( QTreeWidgetItem*, int) ), this, SLOT( itemChecked( QTreeWidgetItem*, int ) ) ); 
Zum Iterieren über die Items würde ich folgendes probieren:

Code: Alles auswählen

void iterateTreeItems(QTreeWidget* treeWidget, QTreeWidgetItem *parent = 0)
{
  int count =  parent ? parent->childCount() : treeWidget->topLevelItemCount();

  for (int i = 0; i < count; i++)
  {
    QTreeWidgetItem *item = parent ? parent->child(i) : treeWidget->topLevelItem(i);

    iterateTreeItems(treeWidget, item);
  }
}


Verfasst: 26. Mai 2010 11:32
von qrk123
Hallo,

ich habe das gerade nocheinmal ausprobiert. Bei der Signalmethode wird itemchecked() immernoch nicht aufgerufen.
Und bei dem zweiten Beispiel versteh ich nicht ganz wofür der Parentparameter da ist und warum er in der Parameterliste mit 0 initialisiert wird. Was muss ich der Funktion als Parameter für Parent übergeben?

Ich hab probiert den Checkstate folgender Maßen zu überprüfen

if(item->checkState(0))
checkedItems << item;

Dabei stürzt das Program aber regelmäßig ab. Ist das falsch? geht es anders?

Steh grad wirklich aufm Schlauch :(

vielen Dank

Verfasst: 26. Mai 2010 12:21
von upsala
Und was sagt der Debugger dazu?

Verfasst: 26. Mai 2010 12:25
von qrk123
Der sagt "Unbehandelte Ausnahme bei 0x6571d006 (QtGuid4.dll) in Composer.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000." ;)

Kann vielleicht jemand diese beiden Zeilen erläutern?

int count = parent ? parent->childCount() : treeWidget->topLevelItemCount();

QTreeWidgetItem *item = parent ? parent->child(i) : treeWidget->topLevelItem(i);

Versteh ich leider nicht :(

Verfasst: 26. Mai 2010 12:36
von franzf
qrk123 hat geschrieben:Der sagt "Unbehandelte Ausnahme bei 0x6571d006 (QtGuid4.dll) in Composer.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000." ;)
Und das sagt dir?

Verfasst: 26. Mai 2010 12:40
von qrk123
Ich glaube, das heißt in diesem Fall, dass ein Parent des Items nicht existiert und er beim Versuch des Zugriffes darauf scheitert. Aber wissen tu ichs nicht.

Verfasst: 26. Mai 2010 12:47
von franzf
qrk123 hat geschrieben:Ich glaube, das heißt in diesem Fall, dass ein Parent des Items nicht existiert und er beim Versuch des Zugriffes darauf scheitert. Aber wissen tu ichs nicht.
Das sagt dir zu allererst dass du irgendwo auf einen Zeiger zugreifen willst, der mit NULL initialisiert ist. Das führt zu der Zugriffsverletzung.
Du schaust jetzt mit dem Debugger, an welcher Stelle genau die Verletzung ausgelöst wird (Callstack/Backtrace). Mit dem Debugger kannst du dir auch den Inhalt der einzelnen Variablen anschauen, vllt. wirst du da schlauer ;).
Da wir den exakten Code nicht vor uns haben, können wir auch nur Tips geben, wie du den Fehler selber finden kannst .

Verfasst: 26. Mai 2010 12:58
von qrk123
Die Itemliste wird in der Funktion scheinbar nicht richtig gesetzt.

Das Programm scheitert nämlich beim ausführen von:
checkedItems.last()->parent()->text(0);

ein checkedItems.last() existiert, scheinbar nur das Parent nciht.

Könnte mir nochmal Jemand etwas zu den beiden Codezeilen aus der Funktion sagen? Count ist bei mir wohl immer der Wert 1. Kann das sein? :(

Ich kann vielleicht nochmal sagen was ich allgemein machen möchte. Mein Ziel ist es in mehreren verschiedenen Trees items zu markieren und aus denen dann einen einzelnen neuen Tree zusammen zu bauen. Ich hoff das kann so funktionieren.

Verfasst: 26. Mai 2010 13:12
von franzf
qrk123 hat geschrieben:Könnte mir nochmal Jemand etwas zu den beiden Codezeilen aus der Funktion sagen?
Google nach "ternärer Operator".
Ist im Prinzip eine Kurzschreibweise für ein if/else.

Verfasst: 26. Mai 2010 13:21
von qrk123
Die Schreibweise verstehe ich, aber ich kann mit dem Übergabeparamter parent nicht viel anfangen. Warum wird der auf 0 gesetzt in der Parameterliste? Wofür braucht man den überhaupt? kann man nicht einfach so in einem Widget über alle items iterieren? Sry, blöde Fragen wahrscheinlich ... :oops:

Verfasst: 26. Mai 2010 13:31
von franzf
qrk123 hat geschrieben:Die Schreibweise verstehe ich, aber ich kann mit dem Übergabeparamter parent nicht viel anfangen. Warum wird der auf 0 gesetzt in der Parameterliste? Wofür braucht man den überhaupt?
Der Hintergedanke ist, dass man das Ding auch rekursiv verwenden kann.
Das "=0" nennt man Default-Parameter, und macht hier speziell mit Pointern Sinn. Wenn das Ding "0" ist, soll das rootItem (also die topLevelItems) genommen werden, ansonsten wird angenommen, parent (der Parameter!) ist valid und von diesem aus werden die childItems iteriert.
Du hast ja eine Baumstruktur, und da macht Rekursion zum tiefen Iterieren Sinn.