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