race condition con QThread / QDialog
-
25-10-2019 - |
Domanda
Sto cercando di evitare una race condition nel seguente scenario:
QDialog* dialog = [...];
QThread* thread = [...];
connect(thread, SIGNAL(finished()), dialog, SLOT(accept()));
thread->start();
dialog->exec();
Al termine del filo prima QDialog :: exec () ha istituito la finestra di dialogo, il "accept ()" chiamata che è stato attivato dal segnale sarà perso e la finestra di dialogo non si chiude in sé ...
Quindi idealmente voglio iniziare il thread solo dopo che la finestra è pronta a gestire la cosa, ma come faccio a fare questo?
Soluzione
Il trucco è che si deve avviare il thread solo quando la finestra è già visualizzato. quindi bisogna avviarlo una volta che lo ShowEvent del QDialog è sollevata.
Prima di tutto bisogna catturare lo ShowEvent, è possibile farlo sia usando QObject::installEventFilter
e QObject::eventFilter
o sottoclasse QDialog
sovrascrivendo QWidget::showEvent
.
Una volta che avete fatto questo, si desidera segnalare il thread per iniziare. Avete bisogno di un segnale personalizzato, che si emettono in YourClass::eventFilter
o in YourClass::showEvent
a seconda da che parte si è scelto di catturare l'evento spettacolo.
Ora è sufficiente collegare il segnale allo slot QThread::start()
e si dovrebbe essere fatto (EDIT: utilizzare un Qt::QueuedConnection
).
Assicuratevi di non gestire il segnale QDialog::accepted()
due volte!
Altri suggerimenti
È stato un po 'che ho usato Qt. Ma perché stai usando un QThread per gestire il clic nella finestra di accettare? È possibile utilizzare QDialog :: risultato () se si tratta di una finestra di dialogo modale o si può inoltrare il segnale dal filo al QDialog :: accettato () ...