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.