Race-condition bei QThread/QDialog
-
25-10-2019 - |
Frage
Ich versuche zu vermeiden, dass eine race condition im folgenden Szenario auf:
QDialog* dialog = [...];
QThread* thread = [...];
connect(thread, SIGNAL(finished()), dialog, SLOT(accept()));
thread->start();
dialog->exec();
Wenn der thread beendet ist, bevor QDialog::exec() gesetzt hat, bis das Dialogfeld, das "accept()" zu nennen, war, ausgelöst durch das signal verloren, und das Dialogfeld wird nicht schließen, selbst...
Also idealerweise beginnen möchte ich den thread erst nach dem dialog ist bereit zu Griff es, aber wie kann ich dies tun?
Lösung
Der trick ist, dass Sie zu starten den thread nur, wenn das Dialogfeld angezeigt wird schon.so haben Sie, um es zu starten, sobald das showEvent des QDialog ausgelöst wird.
Zuerst müssen Sie zu erfassen die showEvent, können Sie dies tun, indem Sie entweder mit QObject::installEventFilter
und QObject::eventFilter
oder Unterklassen QDialog
überschreiben QWidget::showEvent
.
Sobald Sie dies getan haben, werden Sie wollen, um zu signalisieren, den thread zu starten.Sie müssen eine benutzerdefinierte signal, das Sie aussenden, in YourClass::eventFilter
oder YourClass::showEvent
je nachdem welchen Weg Sie gewählt haben, erfassen Sie das show-Ereignis.
Nun verbinden Sie das signal an den QThread::start()
slot und Sie sollte getan werden (BEARBEITEN:verwenden Sie ein Qt::QueuedConnection
).
Stellen Sie sicher, dass Sie nicht den Griff QDialog::accepted()
signal zweimal!
Andere Tipps
War eine Weile, seit ich Qt verwendet habe. Aber warum verwenden Sie ein QThread, um den Akzeptierenklick aus dem Dialog zu verarbeiten? Sie können QDialog :: result () verwenden, wenn es sich um einen modalen Dialog handelt oder Sie das Signal vom Thread an QDialog :: Accepted () weiterleiten können ...