如何避免Qt app.exec()阻塞主线程

Sid*_*tha 17 c++ qt multithreading

我是Qt的新手,但需要解决一个棘手的问题.

我创建了一个非常简单的GUI,我需要将其添加到现有的C++应用程序中.问题是,我只写了一个插入更大架构的模块,这限制了我对主线程的访问.

我的代码必须驻留在以下四个函数中:一个Init()函数,它在主线程中运行.和在工作线程中运行的WorkerStart(),WorkerStep()和WorkerStop()函数.

我在Init()函数中编写了我的QApplication和GUI对象.但是,当然,在该函数末尾调用app.exec()会阻止整个代码.不可行.

我正在阅读的所有东西都说Qt gui对象只能在主线程中运行.

所以我的问题是,如何在init()函数(主线程)中设置我的gui并允许它从那时起仅使用工作线程运行?

我发现了这个:非主线程中的QApplication

那些解决方案给了我一些不同的行为.在正确的方向,但不稳定或完全功能.但我不明白为什么这些解决方案根本不存在qt gui只能在主线程中运行,而这些解决方案将它们放在其他线程中.因此,在其他线程中发送可以和不可以运行的内容的混合消息,这变得非常混乱.

似乎在现有的C++程序中添加gui而不将其锁定在exec()函数中应该是一个相当常见的情况,所以我觉得我错过了一些明显的东西.有人可以帮我解决这个问题吗?

非常感谢提前.菲尔

JKS*_*KSH 21

大多数时候,"主线程"=="GUI线程",所以人们可以互换使用这些术语 - 甚至官方文档都这样做.我同意它很混乱,因为它们不必相同.^实际的规则是这样的:

只能从实例化QApplication/ 的线程访问GUI类QGuiApplication

使用像你这样的插件,这是你需要做的:

  1. 创建一个新的std::thread(不是QThread)
  2. init在该线程中运行一个函数.让它实例化你的QApplication/ QGuiApplication并启动事件循环
  3. 确保仅从该线程访问所有GUI对象.

瞧,你现在有一个不是主线程的GUI线程.


^ 注意:在Mac OS X上它是一个不同的故事.由于Cocoa框架的限制,主线程必须是GUI线程.我上面概述的步骤适用于Windows/Linux,但不适用于Mac.对于Mac,您需要将代码注入主线程 - 请参阅下面的Kuba Ober的评论.

  • 在OS X上,将代码注入主线程非常简单:`dispatch_sync(dispatch_get_main_queue(),^ {/*do stuff*/});`你也可以在该线程中运行Qt的事件循环,因为它运行本机事件循环. (2认同)