[gelöst]Kommunikation zwischen GuiThread/Thread

Alles rund um die Programmierung mit Qt
Antworten
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

[gelöst]Kommunikation zwischen GuiThread/Thread

Beitrag von woody »

Hi, habe ein Problem:
Ich habe eine GUI Applikation, die mit einem Thread arbeitet. Ich erzeuge ein Objekt(abgeleitet von QObject mit Q_OBJECT Makro), dass eine Methode create hat und einen aufwendigen Prozess in einem eigenen Thread abarbeiten soll. Also erzeuge ich auch einen abgeleiteten QThread der in der run Methode exec(); aufruft.
Mit

Code: Alles auswählen

my_object->moveToThread(my_thread);
verschiebe ich mein Objekt in den Thread und verbinde alle nötigen Signale und Slots.
Bei den Komminkationsslots ist meist der Guithread der Empfänger und das Object im Thread der Sender(z.B senden eined Status oder Fehler der in MessageBox angezeigt wird.).

Nur während des Prozesses im Thread kann es sein, dass vom User eine Entscheidung getroffen werden muss. So sendet der Thread mit emit ein Signal mit einer QList<IrgendeinObject*>* als Parameter. Nach dem Senden dieses Signals wird im Thread Object eine QEventLoop mit exec gestartet.

Code: Alles auswählen

            emit signal(list_irgendeinobject);
            qDebug() << " - Waitloop START";
            waitloop.exec();
            qDebug() << " - Waitloop END";
Der MainThread hat einen Slot, der durch dieses Signal ausgeführt wird und zeigt die Möglichkeiten in einem QTableWidget an. Der User wählt aus und das Ergebnis wieder eine QList<>* soll mit einem Signal emit an einen Slot des Objekts im Thread gesendet werden.

Code: Alles auswählen

void My_Object::result_slot(QList<Field *> *decide_list)
{
    qDebug() << "BaseExport::decided(QList<MatchingSetField *> *decide_list)";

    waitloop.quit();
}

Jetzt treten Probleme auf: Bei einem DualCore Prozessor wird der Slot ausgeführt, aber ca. alle 10 mal tritt dieser Fehler auf:

Code: Alles auswählen

QPixmap: It is not safe to use pixmaps outside the GUI thread 
QPixmap: It is not safe to use pixmaps outside the GUI thread
und das Programm stürzt ab.
Bei einem Single Core Prozessor wird der Slot nie ausgeführt.

Die Kommunikationsslots sind alle Qt::QueuedConnection.

Ist die QEventLoop das Problem, denn ich habe ja im Thread eine EventLoop wegen exec(), und dann auch im Objekt, während es auf die Antwort wartet...

Kann mir jemand helfen?? = )
Zuletzt geändert von woody am 22. Mai 2012 13:46, insgesamt 2-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Kommunikation zwischen GuiThread und Object in QThread

Beitrag von franzf »

In deinem Code seh ich nirgendwo ein QPixmap, geschweige denn eine Stelle, an der ein SegFault entstehen könnte. Auch fehlt eine Backtrace im Falle des SegFault oder rigendwie relevanter Code. Daher wird das Beste sein, du packst deinen Quelltext (incl. .pro/resourcen, ... aber OHNE Binaries, Libs, Qt-Libs, etc) in ein .zip und hängst es hier im Forum mit "Dateianhang hochladen" an.
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

Re: Kommunikation zwischen GuiThread und Object in QThread

Beitrag von woody »

Hi,
hab ein kleines Testprojekt zusammengestellt. Prinzip, wie oben beschrieben und es treten immer wieder Fehler bei der Ausführung auf.

Im Anhang das TestProjekt...

Danke für die Hilfe!
Dateianhänge
guithread_thread_communication.zip
(6 KiB) 134-mal heruntergeladen
woody
Beiträge: 85
Registriert: 1. April 2011 21:13

Re: Kommunikation zwischen GuiThread und Object in QThread

Beitrag von woody »

Habe das Problem gelöst. Die zweite EventLoop war das Problem.
Wenn man das Signal vom Thread mit dem Slot vom GuiThread connected verwende ich jetzt den ConnectionType BlockingQueuedConnection.

Wenn jetzt der Thread das Signal sendet, bleibt der Thread solange geblockt, bis der Slot des GuiThreads ausgeführt ist.
Der GuiThread darf das Ergebnis aber nicht als Signal zurück zum Thread senden, sondern verändert nur die QList hinter dem Pointer, den der Thread zur Verfügung stellt.
Somit hat der Thread das Ergebnis gleich nach Ausführung des Slots im GuiThread....

Die EventLoop kann man sich sparen in diesem Fall.
Antworten