Seite 1 von 1

Qt Threads Anzeige akutalisieren

Verfasst: 28.02.2012, 20:50
von Jonathan
Ich habe ein paar längere Berechnungen und möchte dafür jetzt Zwischenergebnisse anzeigen. Mit einem QThread konnte man die Berechnung auch sehr einfach auslagern, ohne dass die GUI blockiert, aber es scheint gar nicht so einfach zu sein, jetzt in der GUI aktuelle Zwischenwerte anzuzeigen. Die Doku sagt nur:
In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished.
Also, dass ich keine GUI-Elemente direkt ansprechen kann, mag ja noch verständlich sein. Aber wenn dieser Signal&Slots Mechanismus über Threads funktioniert, dann müsste es doch eigentlich gehen, wenn ich aus dem Arbeitsthread ein Signal im Hauptthread aufrufe und dort das Widget aktualisiere? Denn ansonsten wäre es wirklich unmöglich, Zwischenzustände anzuzeigen? Das kann ich mir irgendwie nicht vorstellen.
Mein Momentaner Ansatz geht etwa so:

Code: Alles auswählen

std::streamsize ConsoleWidgetStream::write(const char* s, std::streamsize n)
{
	emit m_Target.Write(std::string(s, (int)n));
	return n;
}
Ich benutze dafür die cout Umleitung aus dem anderen Thread. Die Ergebnisse sollen also im Arbeitsthread mit cout ausgegeben werden und im Hauptthread in der Konsole (als Qt Widget) ausgegeben werden. Aber ich krieg immer die Assertion, dass ich keine Signale von Objekten aufrufen kann, die meinem Thread nicht gehören.

Wie kann ich das lösen/umgehen?

Re: Qt Threads Anzeige akutalisieren

Verfasst: 29.02.2012, 09:07
von Schrompf
Du kannst Connections als "queued" definieren. Damit werden angeschlossene Slots nicht direkt im Aufrufer-Thread ausgeführt, sondern der Aufruf wird zwischengespeichert und dann als Teil der InputEvent-Verarbeitung in der Message Queue des Zielthreads ausgeführt. Praktische Geschichte, erspart einem jede Thread-Sicherung.

Re: Qt Threads Anzeige akutalisieren

Verfasst: 29.02.2012, 09:39
von kimmi
Das ist gut zu wissen, ebenfalls danke für den Tipp!

Gruß Kimmi

Re: Qt Threads Anzeige akutalisieren

Verfasst: 29.02.2012, 15:46
von Jonathan
Mir ist aufgefallen, dass ich emit auf den slot und nicht das signal angewendet habe. Macht wohl irgendwie keinen Sinn.
Wenn ich mir einen slot definiere, die connecte und den dann emite, geht es.

Allerdings hatte ich dann noch das Problem, dass QPalinTextEdit::setPlainText unglaublich langsam ist, und so mein Hauptthread mit mehr Signalen zugeballert wurde, als er bearbeiten konnte, so dass das Programm wieder auf keinerlei Events mehr reagierte (und auch die Konsole nichts mehr anzeigte), bis der Thread zuende war.
Lösen konnte ich dass dann mit einem blockierenden Signal, dass einfach einen leeren Slot der Hauptfunkion aufruft. Das wird während der Berechnung immer wieder mal aufgerufen, so dass der Hauptthread in regelmäßigen Abständen Zeit hat, seine Events zu verarbeiten. Das funktioniert wesentlich besser und exakter, als ein zeitbasiertes Sleep und ist ja auch von der Grundidee her sehr viel sinnvoller.