QTreeWidget und QThreads

Alles rund um die Programmierung mit Qt
Antworten
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

QTreeWidget und QThreads

Beitrag von john »

Hallo Leute,

kann man ein QTreeWidget in einem seperaten QThread aufbauen lassen? Also, ich übergebe den Zeiger (des QTreeWidgets) an einem QThread-Object. Dann lasse ich den QThread arbeiten um die QTreeWidgetItems zu erzeugen und einzufügen.

Aber leider kommt während der Laufzeit des Programms folgende Meldung:
QObject::connect: Cannot queue arguments of type 'QModelIndex'
Und auf der GUI sehe ich nur ein leeres QTreeWidget. Hat jemand einen Tipp, oder klappt das ganze nicht in einem Vererbten QThread-Object?

Vielen Dank schonmal!
Grüße John
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

Beitrag von john »

Hi,

also man kann das QTreeWidget in einem seperaten QThread mit Items füllen (bzw. den Baum aufbauen).
Und jetzt das große 'ABER' nur:

-wenn man im GUI-Thread solange wartet, bis der andere Thread fertig ist

Code: Alles auswählen

while(treeThread->isRunning()) {;}
Ansonsten baut sich der Baum manchmal (optisch) gar nicht auf, oder nicht vollständig. Um es zu verdeutlichen:

wenn man nach

Code: Alles auswählen

treeThread->start();
ein

Code: Alles auswählen

Sleep(int);
setzt, dann baut sich der Baum eben nur solange auf, wie Sleep() benötigt. Oder man wartet eben solange, bis der Thread fertig ist. -Aber das kann es doch nicht sein oder?

Irgendwelche Einfälle? -wäre echt sehr dankbar. Noch eins, was bedeutet folgende Meldung?
QObject::connect: Cannot queue arguments of type 'QModelIndex'
Sie erscheint seltsamerweise fünfmal, wenn der Thread gestarted wird, obwohl ich dem Thread schon längst die Adresse (den Zeiger) vom QTreeWidget übergeben habe. Wie gesagt, wenn man im GUI-Thread wartet bis der andere Thread fertig ist, dann klappt alles und der Baum baut sich auf. -Aber das ist ja nicht Sinn der Sache. (die Meldung erscheint trozdem).

Vielen Dank schonmal und viele Grüße
john

PS.:wenn sich der Baum nur halb aufbaut und man mit

Code: Alles auswählen

QTreeWidget::topLevelItemCount();
abfrägt, dann sind doch alle Items 100% vorhanden. Sie werden nur nicht angezeigt.
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Moin
Lies mal auf dieser Seirte http://doc.trolltech.com/4.1/threads.html folgenden Satz ;)
In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.

Goos
uhu01
Beiträge: 150
Registriert: 10. Juli 2005 20:46

Beitrag von uhu01 »

Hy!

Man kann jedoch bei connect den Parameter Qt::queuedConnection übergeben, da in diesem Fall nicht der Worker-Thread den Slot direkt aufruft, sondern diesen in eine Liste packt, welche beim nächsten Durchlauf der Event-Loop vom Gui-Thread selbst aufgerufen wird. Kein anderer Thread führt also Gui-Operationen durch.

mfg
uhu01
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

Beitrag von john »

Hallo und Danke für die Antworten!

Ich dachte mir das auch so (oder so ähnlich;) ), wie es "uhu01" beschrieben hat. Vielen Dank für die klare Erklärung. Jetzt gibt auch die Fehlermeldung:
QObject::connect: Cannot queue arguments of type 'QModelIndex'
einen Sinn. Jedoch weiß ich nicht, wo die "Connection" stadtfindet bzw. wo soll man diese herstellen. Ich übergebe den Worker-Thread den Zeiger auf das QTreeWidget. Nun erstellt und fügt der Worker-Thread die QTreeWidgetItems ein.

@uhu01: welchen Slot meinst du? Ich denke wenn ich nun einen connect vom Worker-Thread mit den Parameter Qt::queuedConnection erstelle müsste es klappen. Bis jetzt habe ich keine Signale mit Slots geconnectet.

Also, kann mir noch wer einen Tipp dazu geben? -Besten Dank!
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Hi john,

vielleicht versuchst doch erstmal zu erklaeren, welcher Gedanke hinter deinem Handeln steht :)
Weshalb willst nen Tree in einem anderen Thread aufbauen?

Goos
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

Beitrag von john »

Goos hat geschrieben:Hi john,

vielleicht versuchst doch erstmal zu erklaeren, welcher Gedanke hinter deinem Handeln steht :)
Weshalb willst nen Tree in einem anderen Thread aufbauen?

Goos
na klar, weil ich einen IP-Bereich abbilden will. Siehe:

Bild

Da können schon einige IP-Adressen zusammen kommen. Ich wollte halt den Baum im Hintergrund aufbauen, neben bei Scannen...
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Entweder versteh ich dich falsch, oder du hast in meinen Augen ein seltsames Vorgehen ;)

Ansich baut man doch den Tree im GUIThread auf, ebenso wie man dort die Progressbars immer weiter setzt. Nebenbei in 1-x Workerthreads wird dann gescannt.
Ist dein Vorgehen anders, oder hab ich nur irgendwas falsch verstanden?

Goos
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

Beitrag von john »

Hallo Goos,
jetzt wo Du es sagts, klingt es wircklich komisch ;-)

Aber wenn ich den Baum im GUI-Thread aufbauen lasse, dann ist die komplette GUI solange Blockiert, bis der Baum fertig ist. Man kann dann nicht mal das Fenster verschieben. Deswegen würde ich den Baum auch in einen seperaten Worker-Thread arbeiten lassen wollen.

Gruß John
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Ach du baust den Baum auf eimal auf?
Wieso nicht erst mit dem Scan der entsprechenden IP?

Goos
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

Beitrag von john »

Goos hat geschrieben:Ach du baust den Baum auf eimal auf?
Wieso nicht erst mit dem Scan der entsprechenden IP?

Goos
ja, der Baum wird zuerst erstellt, dann kann der Scan-Vorgang losgehen. Das beste wäre wircklich den Baum um jeden Rechner zu ergänzen. Werde darüber nachdenken. -Danke für den Hinweis!

In der Newsgroup von Trolltech bekam ich folgende Antwort:
Did you try about creating a QList of the top-level items and adding that via addTopLevelItems?
Dann könnte es vielleicht auch in einem anderen Thread funktionieren.

Mal sehen, jetzt habe ich vieles zu probieren.

Ciao John[/quote]
john
Beiträge: 110
Registriert: 14. August 2004 20:55
Wohnort: München

Beitrag von john »

Hallo, nur zur Info, es funktioniert jetzt perfekt!!

so hab ich's gemacht:
Did you try about creating a QList of the top-level items and adding that via addTopLevelItems?
:-)

Gruß John
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Nochmal ins deutsche .... alles was mit ausgaben aufn bildschirm zu tun hat, sollte tunlichst von nur einem thread erledigt werden ....

Sprich wenn irgend ein Anderer Thread auf deinem QListView rumfummelt, sind probleme vorprogrammiert ....

wie genau du das listview fuellst, iss dabei deine Sache ....

In Windows (win32, mfc ATL etc) nutzt man dazu meist die MessageQueue
da schreiben mehrere Threads in die queue (PostMessage) aber nur der Mainthread(GUI Thread) liest die events aus ....

Das kannt mit QT ab version 4 auch,d a signale nu ueber threads hinweg funktionieren, also quasi entkoppelt werden ....

Sprich dein Mainwindow bzw dein listview implementieren slots, die wenn die angesprungen werden dein Listview aktualisieren ....

Dein Abreitsthread beispielsweisse braucht dann nur noch seine arbeit zu tun (scannen) und wenn ergebnisse vorliegen einfach ueber ein signal, welches mit dem slot im Mainwindow bzw dein listview verbunden ist, das aktualisieren veranlassen.
Wenn innerhalb der Signal / Slot parameter keine Objectreferenzen euberhgeben werden die threadkritisch sind (am besten nimmt ma PODs per kopie), sollte es keine probleme geben.

Ciao ...
Antworten