Hallo, bei QT ist mir bekannt, dass nur der mainwindow Thread Änderungen GUI-Operationen zulässt. Soweit klar. Frage: wenn ich mit QT neben dem mainwindow eine eigene QT-Designer-Formularklasse erstelle und die Zeile in der .cpp der neuen Formularklasse ist so: Fenster::Fenster(QWidget *parent) : QWidget(parent, Qt::Window), ui(new Ui::Fenster) und sorgt dafür, dass über das mainwindow über zb einen Button sich ein neues Fenster öffnet. In mainwindow.cpp steht dann beim Buttonclick: fenster = new Fenster(this); fenster->show(); Frage1: gehört dieses zusätzliche QWidget Fenster dann auch zum mainwindow Thread? Frage2: Ist es möglich, dass Hintergrund-Worker-Threads je nach Bedarf im MainWindow sowie in weiteren solcher QWidget-Fenstern GUI Operationen ausführen können? Beispiel ein Workerthread ändert ab und zu in MainWindow die Anzeige einer Zahl und andere Workerthreads ändern im QWidget-Fenster irgendwelche Werte in Zeilen in einer Tabelle. Frage3: Wenn Werte aus Workerthreads in jeweils einer eigenen Zeile einer Tabelle eines QWidget-Fensters angezeigt und regelmäßig aktualisiert werden sollen, gibt es irgendwelche Probleme mit gleichzeitigen GUI-Operationen der verschiedenen Threads? Muss das global dann per Mutex Synchronisiert werden oder kümmert sich QT darum wenn es mehrere GUI-Operationsanweisungen zugleich gibt? Grüße
Alle GUI-Elemente, die du aus dem „Main“-Thread heraus anlegst, sind immer im richtigen Thread. Kommunikation aus Worker-Threads mit dem GUI über direkte Funktionsaufrufe geht schief. Gemeinerweise funktioniert das manchmal doch, und Fehlermeldungen bekommst du auch nicht, so daß solche Fehler nicht immer offensichtlich sind. Das geht sicher über den Signal/Slot-Mechanismus, der sorgt im Hintergrund für einen korrekte Zuordnung der Aufrufe zu den Threads. Und natürlich sind alle nicht „thread-safen“ Methoden und Funktionen mit Mutexen zu synchronisieren. Oliver
:
Bearbeitet durch User
> Alle GUI-Elemente, die du aus dem „Main“-Thread heraus anlegst, sind > immer im richtigen Thread. was heißt richtiger Thread, gibt es falsche Threads? QWidget-Fenster haben dann einen eigenen GUI-Thread oder gehören zum GUI-MainThread? > Kommunikation aus Worker-Threads mit dem GUI über direkte > Funktionsaufrufe geht schief. Gemeinerweise funktioniert das manchmal > doch, und Fehlermeldungen bekommst du auch nicht, so daß solche Fehler > nicht immer offensichtlich sind. > > Das geht sicher über den Signal/Slot-Mechanismus, der sorgt im > Hintergrund für einen korrekte Zuordnung der Aufrufe zu den Threads. Ja der Signal/Slot-Mechanismus um im in der Main-GUI was zu ändern ist klar da hab ich auch schon ansätze gefunden: zb: https://stackoverflow.com/questions/14545961/modify-qt-gui-from-background-worker-thread Was ich noch nicht verstehe ist, wie das Ganze bei zusätzlichen QWidget-Fenstern, wie oben beschrieben, dann funktioniert.
C++Lotte schrieb: > Hallo, > > bei QT ist mir bekannt, dass nur der mainwindow Thread Änderungen > GUI-Operationen zulässt. Soweit klar. Das hat nicht speziell mit einem MainWindow zu tun. QMainWindow ist auch nur ein Widget wie jedes andere. In Qt sind die Instanzen der von QObject abgeleiteten Klassen immer an einen Thread gebunden. Alle GUI-Elememte müssen im Hauptthread "leben". Die Qt-Doku sagt es so: "As mentioned, each program has one thread when it is started. This thread is called the "main thread" (also known as the "GUI thread" in Qt applications). The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. A secondary thread is commonly referred to as a "worker thread" because it is used to offload processing work from the main thread." > Frage: wenn ich mit QT neben dem mainwindow eine eigene > QT-Designer-Formularklasse erstelle und die Zeile in der .cpp der neuen > Formularklasse ist so: > Fenster::Fenster(QWidget *parent) : QWidget(parent, Qt::Window), ui(new > Ui::Fenster) > und sorgt dafür, dass über das mainwindow über zb einen Button sich ein > neues Fenster öffnet. In mainwindow.cpp steht dann beim Buttonclick: > fenster = new Fenster(this); > fenster->show(); > > Frage1: > gehört dieses zusätzliche QWidget Fenster dann auch zum mainwindow > Thread? Zum "main thread", ja. > Frage2: > Ist es möglich, dass Hintergrund-Worker-Threads je nach Bedarf im > MainWindow sowie in weiteren solcher QWidget-Fenstern GUI Operationen > ausführen können? Nein, die müssen immer von dem Thread aus ausgeführt werden, zu dem das entsprechende Objekt gehört - also für alle QWidgets vom main thread. > Beispiel ein Workerthread ändert ab und zu in MainWindow die Anzeige > einer Zahl und andere Workerthreads ändern im QWidget-Fenster > irgendwelche Werte in Zeilen in einer Tabelle. Nicht bei direktem Funktionsaufruf, aber bei Signal-Slot-Verbindungen geht das. Diese Verbindungen können nämlich auf mehrere Arten gemacht werden, und wenn Quell- und Zielobjekt in unterschiedlichen Threads leben, wird automatisch eine "queued connection" erzeugt. Das heißt, der Aufruf wird durch die Event-Loop geschleust. > Frage3: > Wenn Werte aus Workerthreads in jeweils einer eigenen Zeile einer > Tabelle eines QWidget-Fensters angezeigt und regelmäßig aktualisiert > werden sollen, gibt es irgendwelche Probleme mit gleichzeitigen > GUI-Operationen der verschiedenen Threads? Ja, gibt es. C++Lotte schrieb: >> Alle GUI-Elemente, die du aus dem „Main“-Thread heraus anlegst, sind >> immer im richtigen Thread. > was heißt richtiger Thread, gibt es falsche Threads? Wie gesagt: Die Funktion eines QObjects dürfen nur aus dem Thread heraus aufgerufen werden, in dem es lebt, es sei denn, die Dokumentation sagt, dass die Funktion Thread Safe ist. Hier nochmal die Qt-Doku (von QObject) dazu: "Thread Affinity A QObject instance is said to have a thread affinity, or that it lives in a certain thread. When a QObject receives a queued signal or a posted event, the slot or event handler will run in the thread that the object lives in. Note: If a QObject has no thread affinity (that is, if thread() returns zero), or if it lives in a thread that has no running event loop, then it cannot receive queued signals or posted events. By default, a QObject lives in the thread in which it is created. An object's thread affinity can be queried using thread() and changed using moveToThread()." > QWidget-Fenster haben dann einen eigenen GUI-Thread oder gehören zum > GUI-MainThread? Ausnahmslos alle Widgets und noch ein paar andere GUI-Objekte müssen in einem gemeinsamen GUI-Thread leben.
C++Lotte schrieb: > Frage1: > gehört dieses zusätzliche QWidget Fenster dann auch zum mainwindow > Thread? Leider hat Qt sehr viel Verwirrung mit den moveToThread Funktionen von QObjests geschaffen, wie man auch an dieser Fragestellung sieht. Ein Objekt/Klasse "gehört" nicht zu einem Thread. Seine Funktionen werden in einem oder anderen Thread ausgeführt, falls die Applikation mehrere hat. Das ist alles.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.