如何避免Qt app.exec()阻塞主线程 [英] How to avoid Qt app.exec() blocking main thread

查看:2815
本文介绍了如何避免Qt app.exec()阻塞主线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Qt的新手,但需要解决一个困难的问题。

I'm new to Qt, but need to solve a difficult problem.

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

I've created a VERY simple GUI that I need to add to an existing C++ application. The problem is, I'm writing just one module that plugs into a larger architecture which restricts my access to the main thread.

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

My code must reside inside the four following functions: an Init() function, which runs in the main thread. and WorkerStart(), WorkerStep(), and WorkerStop() functions that run in a worker thread.

我编写了我的QApplication和GUI对象()函数。但是,当然,调用app.exec()在该函数的末尾阻塞了整个代码的其余部分。不可行。

I coded my QApplication and GUI objects in the Init() function. But of course, calling app.exec() at the end of that function blocks the entire rest of the code. Not workable.

我正在阅读的所有内容都表示Qt gui对象只能在主线程中运行。

Everything I'm reading says that Qt gui objects can only run in the main thread.

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

So my question is, how can I set up my gui in the init() function (main thread) and allow it to run by only using the worker thread from then on?

我发现:非主线程中的QApplication

这些解决方案给了我一些不同的行为。在正确的方向,但不稳定或完全功能。但我不明白为什么这些是解决方案,如果qt gui只能运行在主线程,这些解决方案把它们在其他线程。所以,发送混合消息,什么可以和不能在其他线程中运行,它变得很混乱。

and those solutions gave me some different behavior. In the right direction, but not stable or fully functional. But I dont understand why those are solutions at all if qt gui's can only run in main thread, and these solutions put them in other threads. So thats sending mixed messages on what can and can not run in other threads, and it becomes very confusing.

似乎添加一个gui到现有的C ++程序没有锁定它在exec()func应该是一个相当普遍的情况,所以我觉得我缺少一些明显的东西。有人可以帮助我如何解决这个问题吗?

It seems that adding a gui to an existing C++ program without locking it up in the exec() func should be a fairly common situation so I feel like I'm missing something obvious. Can someone help with how I can solve this?

提前非常感谢。
Phil

Much thanks in advance. Phil

推荐答案

大多数时候,主线程==GUI线程术语可互换 - 即使官方文件也是如此。我实际的规则是这样:

Most of the time, "main thread" == "GUI thread", so people use those terms interchangeably -- even the official documentation does that. I agree that it's confusing though, because they don't have to be the same.^ The actual rule is this:


GUI类必须只能从实例化 QApplication / QGuiApplication

使用类似于您的插件,这里是您需要做的:

With a plugin like yours, here is what you need to do:


  1. 创建一个新 std :: thread (不是 QThread

  2. 运行 init 函数。让它实例化您的 QApplication / QGuiApplication 并启动事件循环

  3. 确保

  1. Create a new std::thread (NOT a QThread)
  2. Run an init function in that thread. Let it instantiate your QApplication/QGuiApplication and start the event loop
  3. Ensure that all your GUI objects are accessed from that thread only.

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

Voila, you now have a GUI thread that is not your main thread.

^ 注意:这是Mac OS X上的一个不同的故事。 Cocoa框架,主线程必须是GUI线程。我上面列出的步骤将在Windows / Linux上运行,但不在Mac上运行。对于Mac,您需要将代码注入主线程 - 请参阅下面的Kuba Ober的注释。

^Note: It is a different story on Mac OS X. Due to restrictions in the Cocoa framework, the main thread MUST be the GUI thread. The steps I outlined above will work on Windows/Linux but not on Mac. For Mac, you need to inject your code into the main thread -- see Kuba Ober's comments below.

这篇关于如何避免Qt app.exec()阻塞主线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆