2010-05-09 96 views
10

我需要在非主线程中运行QApplication(我的GUI必须是可以在运行时动态加载和卸载的插件,所以我无法访问主线程) 。有没有人知道一种(相对)无痛的方式来解决Qt对主要启动QApplication的限制?在非主线程中的QApplication

我正在使用gcc4.3.4在C++中用Qt4开发Linux。

回答

4

如果你正在使用QThread,那么你已经有了正常的Qt事件循环,并且可以在QThread :: run()函数内运行exec()。虽然您无法使用主线程之外的GUI对象,但您仍然可以通过排队的信号/插槽连接与它们进行交互。也许你可以尝试存储指向主线程QThread对象的指针,并调用QObject :: moveToThread()将GUI对象移动到主线程,而不是将QApplication移动到另一个线程中。

我认为尝试用不同类型的黑客和诡计反对工具包并不是一个好主意。

+0

我认为你可能是对的,VestniK - 虽然我的GUI确实运行,但它似乎并没有实际服务update()调用,除非我强制操作系统通过在其上拖动另一个窗口重新绘制GUI。 – rcv 2010-05-09 22:45:47

+0

我发现这个答案对于解决另一个问题很有用,但是当将QMainWindow对象从另一个线程移动到主线程时,我收到了'QObject :: moveToThread:Widgets无法移动到新线程' – ASten 2014-01-05 20:54:08

1

好的,我得到了一些工作!这不太好,但它确实能完成这项工作。

  1. 创建与所有在它实际GUI代码的QMainWindow衍生物和重载这个类的事件()函数来调用这个 - >显示()

  2. 创建一个类(姑且称之为Runner),它将持有一个指向你的QMainWindow衍生物的指针,并给它一个运行函数。

  3. 在亚军::亚军(),启动)一个线程,它将调用亚军:: run()的

  4. 在亚军::运行((这是现在在它自己的线程中运行)构建一个QApplication,以及一个QMainWindow派生实例。调用QApplication的exec()函数。

  5. 现在,当你想启动你的GUI时,只要将任何事件发布到你的QMainWindow衍生物上,它就会显示出来!

该解决方案似乎是在Linux下工作得很好,但它似乎真的被利用Qt中的一些漏洞,也不能在其他平台上工作。绝对比修补Qt更容易。

+0

Hey Boatzart,我正在努力实现同样的目标。当你说“Runner :: Runner()”时,启动一个将调用Runner :: run()的线程,你的意思是什么。启动另一个启动亚军螺纹的QThread?但是如何在不构建QApplication的情况下启动另一个线程? – blueskin 2012-06-25 04:15:21

8

您可以在并行线程启动的QApplication如下

//main.cpp

#include <iostream> 
#include "appthread.h" 
int main(int argc, char *argv[]) { 
    InputArgs args = {argc, argv}; 
    StartAppThread(args); 
    sleep(10); 
    return 0; 
} 

//appthread.h

struct InputArgs{ 
    int argc; 
    char **argv; 
}; 
void StartAppThread(InputArgs &); 

//appthread.cpp

​​