QTreeView und Checkboxen

Alles rund um die Programmierung mit Qt
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

QTreeView und Checkboxen

Beitrag 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
Zuletzt geändert von qrk123 am 26. Mai 2010 11:55, insgesamt 1-mal geändert.
stefanborries
Beiträge: 6
Registriert: 29. Oktober 2009 11:58

Alle Items durchsuchen

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

Beitrag von upsala »

Mal davon abgesehen, daß der connect so nie funktionieren kann, geschweige denn kompiliert werden kann.
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

Beitrag 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. :(
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Beitrag 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);
  }
}

Zuletzt geändert von brax am 27. Mai 2010 12:00, insgesamt 1-mal geändert.
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

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

Beitrag von upsala »

Und was sagt der Debugger dazu?
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

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

Beitrag 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?
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

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

Beitrag 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 .
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

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

Beitrag 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.
qrk123
Beiträge: 32
Registriert: 4. Dezember 2009 13:19

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

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