qthread/qdialogを使用したレース状態
-
25-10-2019 - |
質問
次のシナリオでは、人種の状態を避けようとしています。
QDialog* dialog = [...];
QThread* thread = [...];
connect(thread, SIGNAL(finished()), dialog, SLOT(accept()));
thread->start();
dialog->exec();
qdialog :: exec()がダイアログを設定する前にスレッドが終了すると、信号によってトリガーされた「accept()」の呼び出しが失われ、ダイアログはそれ自体を閉じません...
理想的には、ダイアログがそれを処理する準備ができた後にのみスレッドを起動したいのですが、これをどのように行いますか?
解決
トリックは、ダイアログが既に表示されている場合にのみスレッドを開始する必要があることです。したがって、Qdialogのshoweventが掲載されたら、開始する必要があります。
まず、ShowEventをキャプチャする必要があります。 QObject::installEventFilter
と QObject::eventFilter
またはサブクラス化によって QDialog
オーバーライド QWidget::showEvent
.
それを行ったら、スレッドを信号にして開始する必要があります。あなたが放出するカスタム信号が必要です YourClass::eventFilter
またはで YourClass::showEvent
ショーイベントをキャプチャする方法に応じて。
次に、その信号をに接続するだけです QThread::start()
スロットとあなたは完了する必要があります(編集: Qt::QueuedConnection
).
処理しないようにしてください QDialog::accepted()
2回信号!
他のヒント
QTを使用してからしばらく経ちました。しかし、なぜqthreadを使用してダイアログからの受け入れクリックを処理しているのですか? qdialog :: result()を使用することもできます。これがモーダルダイアログである場合、またはスレッドからqdialog :: accepted()に信号を転送できます。