Qt Threads Anzeige akutalisieren

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2659
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Qt Threads Anzeige akutalisieren

Beitrag 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?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 5162
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Qt Threads Anzeige akutalisieren

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
kimmi
Moderator
Beiträge: 1412
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Qt Threads Anzeige akutalisieren

Beitrag von kimmi »

Das ist gut zu wissen, ebenfalls danke für den Tipp!

Gruß Kimmi
Benutzeravatar
Jonathan
Establishment
Beiträge: 2659
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Qt Threads Anzeige akutalisieren

Beitrag 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.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten