我需要在一个非主要的线程中执行()一个QApplication(我的GUI必须是可以在运行时动态加载和卸载的插件,因此我无法访问主线程)。有没有人知道(相对)无痛的方式来破解Qt限制在主要之外启动QApplication?
我正在使用gcc4.3.4在C ++中用Qt4开发Linux。
如果你正在使用QThread,那么你已经有了正常的Qt事件循环,并且可以在QThread :: run()函数中运行exec()。虽然您无法使用主线程之外的GUI对象,但您仍然可以通过排队的信号/插槽连接与它们进行交互。也许你可以尝试存储指向主线程QThread对象的指针,并调用QObject :: moveToThread()将GUI对象移动到主线程,而不是将QApplication移动到另一个线程。
我认为尝试使用不同类型的黑客和kluges来反对工具包并不是一个好主意。
您可以在PThread中启动QApplication,如下所示
#include <iostream>
#include "appthread.h"
int main(int argc, char *argv[]) {
InputArgs args = {argc, argv};
StartAppThread(args);
sleep(10);
return 0;
}
struct InputArgs{
int argc;
char **argv;
};
void StartAppThread(InputArgs &);
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include "appthread.h"
#include <pthread.h>
void *StartQAppThread(void *threadArg) {
InputArgs *args = (struct InputArgs*) threadArg;
QApplication app(args->argc, args->argv);
QMainWindow w;
w.show();
w.setCentralWidget(new QPushButton("NewButton"));
app.exec();
pthread_exit(NULL);
}
void StartAppThread(InputArgs &args) {
pthread_t thread1;
int rc = pthread_create(&thread1, NULL, StartQAppThread, (void*)&args);
}
补丁Qt,我想并删除主线程检查,并测试是否适合您。根据http://bugreports.qt-project.org/browse/QTBUG-7393的说法,它不适用于OS X / Cocoa,因为Cocoa假设第一个线程产生为主/ UI线程。
好的,我有一些有用的东西!它不漂亮,但绝对能胜任。
这个解决方案似乎在Linux中运行得很好,虽然它似乎正在利用Qt中的一些漏洞而且可能无法在其他平台上运行。绝对比修补Qt容易。
用花哨的lambda和C ++线程加2美分:
#include "mainwindow.h"
#include <QApplication>
#include <thread>
int main(int argc, char *argv[])
{
std::thread t1
(
[&]
{
QApplication a(argc, argv);
qInstallMessageHandler(MainWindow::qtMessageOutput);
MainWindow w;
w.show();
return a.exec();
}
);
t1.join();
}
在这里Mainwindow
可以是你的QMainWindow
。