Condición de carrera con qthread/qdialog
-
25-10-2019 - |
Pregunta
Estoy tratando de evitar una condición de carrera en el siguiente escenario:
QDialog* dialog = [...];
QThread* thread = [...];
connect(thread, SIGNAL(finished()), dialog, SLOT(accept()));
thread->start();
dialog->exec();
Cuando el hilo termina antes de QDialog :: Exec () ha configurado el cuadro de diálogo, la llamada "Aceptar ()" que fue activada por la señal se perderá y el cuadro de diálogo no se cerrará ...
Así que idealmente quiero comenzar el hilo solo después de que el diálogo esté listo para manejarlo, pero ¿cómo haría esto?
Solución
El truco es que tienes que iniciar el hilo solo cuando ya se muestra el diálogo. Así que debe comenzar una vez que se plantee el espectáculo del QDialog.
Primero tienes que capturar el showEvent, puedes hacerlo usando ya sea usando QObject::installEventFilter
y QObject::eventFilter
o subclase QDialog
primordial QWidget::showEvent
.
Una vez que haya hecho eso, desea indicar que el hilo se inicie. Necesita una señal personalizada, en la que emite YourClass::eventFilter
o YourClass::showEvent
Dependiendo de qué manera eligió capturar el evento del espectáculo.
Ahora simplemente conecte esa señal al QThread::start()
ranura y debe hacerse (editar: use un Qt::QueuedConnection
).
Asegúrese de no manejar el QDialog::accepted()
señal dos veces!
Otros consejos
Fue un tiempo desde que usé Qt. Pero, ¿por qué está utilizando un Qthread para manejar el clic de aceptar desde el cuadro de diálogo? Puede usar qdialog :: resultado () si es un diálogo modal o puede reenviar la señal del hilo a qdialog :: aceptado () ...