I am doing some work in a QThread reimplementation. Every now and then, I'd like to ask the user a Yes/No question, so I was planning on using QMessageBox::question(). Problem is, I can't call it from the thread. That's not a big one, I can emit a signal that connects to a slot in the main GUI thread which will display the message box, but I also need the custom thread to block and wait for the message box to be dismissed and retrieve the return value as well (here, a QMessageBox::StandardButton). How do I get around to doing that?
EDIT: Will the following (pseudo-)code do the trick?
class MyThread
{
public:
MyThread(QObject *parent)
{
connect(this, SIGNAL(inputRequired()), parent, SLOT(popMsgBox()), Qt::QueuedConnection);
}
void MyThread::run()
{
QMutex m;
for (...)
{
if (something)
{
m.lock();
emit inputRequired();
w.wait(&m);
m.unlock();
}
if (MyGui->ans_ == Yes) do_something();
}
}
signals:
void inputRequired();
protected:
QWaitCondition w;
};
void MyGui::popMsgBox()
{
ans_ = QMessageBox::question(this, "Question", "Yes or no?", Yes | No);
MyThread->w->开发者_高级运维;wakeAll();
}
Simple answer - use a condition.
http://doc.qt.io/qt-5/qwaitcondition.html
If you are working with signals and slots anyway, you can also use the Qt::BlockingQueuedConnection connection type. This connection will wait until the slot (in another thread) is finished executing. Be careful not to deadlock though.
精彩评论