我是Qt的新手,但需要解决一个棘手的问题。
我创建了一个非常简单的GUI,我需要将其添加到现有的C ++应用程序中。问题是,我只编写了一个插入更大架构的模块,这限制了我对主线程的访问。
我的代码必须位于以下四个函数中: 一个Init()函数,它在主线程中运行。 和在工作线程中运行的WorkerStart(),WorkerStep()和WorkerStop()函数。
我在Init()函数中编写了我的QApplication和GUI对象。但是,当然,在该函数末尾调用app.exec()会阻止整个代码。不可行。
我正在阅读的所有内容都说Qt gui对象只能在主线程中运行。
所以我的问题是,如何在init()函数(主线程)中设置我的gui并允许它从那时起仅使用工作线程运行?
我发现了这个:QApplication In Non-Main Thread
这些解决方案给了我一些不同的行为。在正确的方向,但不稳定或完全功能。但我不明白为什么这些解决方案根本不存在qt gui只能在主线程中运行,而这些解决方案将它们放在其他线程中。所以那就是在其他线程中可以运行和不运行的内容上发送混合消息,这会变得非常混乱。
似乎在现有的C ++程序中添加gui而不将其锁定在exec()函数中应该是一个相当常见的情况,所以我觉得我错过了一些明显的东西。有人可以帮我解决这个问题吗?
提前非常感谢。 菲尔
答案 0 :(得分:21)
大多数时候,“主线程”==“GUI线程”,所以人们可以互换地使用这些术语 - 甚至官方文档都这样做。我同意这很令人困惑,因为它们不一定是相同的。^实际的规则是:
只能从实例化
的线程访问GUI类QApplication
/QGuiApplication
使用像你这样的插件,这是你需要做的:
std::thread
(不是QThread
)init
函数。让它实例化您的QApplication
/ QGuiApplication
并启动事件循环Voila,你现在有一个不是你主线的GUI线程。
^ 注意:在Mac OS X上有一个不同的故事。由于Cocoa框架的限制,主线程必须是GUI线程。我上面概述的步骤适用于Windows / Linux,但不适用于Mac。对于Mac,您需要将代码注入主线程 - 请参阅下面的Kuba Ober的评论。
答案 1 :(得分:0)
一个好的解决方案位于:git@github.com:midjji / convenient_multithreaded_qt_gui.git
那只是例如
run_in_gui_thread(new RunEventImpl([](){
QMainWindow* window=new QMainWindow();
window->show();
}));
随时可以在任何线程中调用,同时还要在bg中为您进行设置。
注意,这还需要创建一个QApplication并在线程中执行它。但如果您已经在某个地方这样做了,也可以使用。