c++ - 如何临时切换到 GUI 线程
问题描述
我有一个需要长时间操作的程序,我在不同的线程上运行这个函数。我需要定期为用户更新信息,所以我向 GUI 线程发送一个信号。但有时我需要用户做出选择,我需要在GUI线程上显示QDialog并在用户选择一个选项时暂停慢线程,当用户完成选择后,将值返回给慢线程并继续它
它应该看起来像这样:
但我不知道如何停止和继续线程以及是否应该这样做。
标题:
class Example:public QObject
{
//...
Q_OBJECT
void mainLoop();
Example();
signals:
void updateGUI(const QString &message);
void sendQuestion(const QString &message);
void continueMainLoop(const QString &answer);
private slots:
void updatuGUIslot(const QString &message);
void showQuestionDialog(const QString &message);
};
来源:
Example::Example()
{
connect(this,&Example::updateGUI,this,&Example::updatuGUIslot);
connect(this,&Example::sendQuestion,this,&Example::showQuestionDialog);
std::thread t(&Example::mainLoop,this);
t.detach();
// in the project it is not in the constructor
}
void Example::mainLoop()
{
while(some condition1)
{
// slow action
if(some condition2)
emit updateGUI("message");
if(some condition3)
{
QString result;
ThreadPtr th = this_thread(); // pseudocode
connect(this,&Example::continueMainLoop,this,[&](const QString &answer)
{
result = answer;
th.continue(); // pseudocode
});
emit sendQuestion("question");
th.wait(); // pseudocode
}
// slow action
}
}
void Example::showQuestionDialog(const QString &message)
{
// show dialog with question
emit continueMainLoop("answer");
}
void Example::updatuGUIslot(const QString &message)
{
// update GUI
}
解决方案
您需要在 condition3 之前使用 BlockingQueuedConnection 调用该方法,以检查用户选择了哪个选项。
bool updateGui ;
QMetaObject::invokeMethod(this, "showDialog",Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, updateGui));
if(updateGui)
{
//update GUI
}
推荐阅读
- sql-server - 在 SQL Server 中使用 partition by 将行的日期增加一个月
- flutter - 如何在文本字段列表中创建填充?
- javascript - 添加到最小日期给出奇怪的结果
- javascript - c3.js面积图:选中一行后面积不透明度消失
- yocto - 如何在配方中使用本地 git 服务器 URL?
- shell - 如何以别名运行 shell 脚本?
- jquery - jQuery 自动完成源为空
- javascript - 如何使用结果 api 响应 proxy_pass 属性
- logging - 带有标签选择器的 Kubernetes 日志不适用于某些标签
- python - 如何使用 pandas 或 numpy 从 JPG 或 PNG 文件中读取文本