[英]Starting Qt GUI from dll (in DLLStart function)
我必須從暴露DLLStart
和DLLStop
的dll啟動Qt GUI。 main中的常規(.exe)方法如下:
int main(int argc, char *argv[]) {
QApplication a(argc, argv); Dialog w;
w.show();
return a.exec();
}
問題在於阻塞了a.exec()
調用,因為在DLLStart
中, DLLStart
需要立即返回(請參見下文)。 任何解決方法? 備注:問題是與“ 將Qt GUI添加到動態庫 ”有一些共同點,但是沒有確切的重復。
/** start module */
int __stdcall DLLStart(void) {
..
QApplication qaDll(ac, av); Dialog w;
w.show();
qaDll.exec();
return 0; // never reached
}
/** stop module */
void __stdcall DLLStop(void) { }
在Windows上工作的一種方法是在單獨的QThread
啟動QApplication
。 它不是便攜式的-在OS X上不起作用(我正在研究修補程序)。
但是,您不需要單獨的線程。 如果將代碼注入正在運行的應用程序,則該應用程序已經具有事件循環。 您只需要創建一個全局QApplication
對象就可以了。 事件循環已經在運行,因此您無需調用exec()
。 Qt的窗口與本機事件循環集成在一起,並且在那方面一切都很好。
您確實需要調用QCoreApplication::processEvents
一次。 它將當前應用程序實例集成到Windows事件循環中,僅此而已。
因此,您的啟動代碼可能如下所示:
static struct Data {
int argc = 1;
char *argv[2] = {strdup("dummy"), {}};
QApplication app{argc, argv};
MainWindow win;
} *d;
static void startup() {
d = new Data;
d->win.show();
d->app.processEvents();
}
static void shutdown() {
delete d;
}
應該在適當的時間(在進程附加和分離時)調用startup()
和shutdown()
)。
舊答案如下。 這不再是最新的了。
下面是一個簡短的示例,有關完整的獨立示例,請參見我的其他答案 。
它不是可移植的,這就是Qt文檔建議不要這樣做的原因。 在Windows上可以正常使用。 主線程不是魔術,不是Windows。 OS X上的可可在某種程度上很笨拙,並且使它變得不可能,顯然:(。
請注意,如果加載DLL的應用程序已經使用Qt,那么您就沒有其他事情要做了。 確保使用相同的C ++編譯器編譯DLL,鏈接到相同的C ++運行時,並使用與應用程序使用的二進制兼容的Qt版本。 然后,您不需要自己的QApplication
實例。 為了完成一些有用的工作,請顯示一個Widget或使用計時器實例化一些QObjects
,這些計時器會使它們變得忙碌。 您也可以使用QMetaObject::invokeMethod(obj, "mySlot", Qt::QueuedConnection)
而不是使用計時器:將在控件返回事件循環時進行調用。
如果這不可能,那么以下是您唯一的選擇。 據我所知,工作正常。
請注意,我在這里有點諷刺:如果您是使用DLL的應用程序的作者,則可以可靠地滿足上一段中的條件。 否則-忘記它。
class AppThread : public QThread {
int & argc;
char ** argv;
int result;
void run() {
QApplication a(argc, argv);
Dialog d;
d.show();
result = a.exec();
}
public:
AppThread(int & argc, char ** argv) : argc(argc), argv(argv) {}
~AppThread() { quit(); wait(); }
}
extern "C" int __stdcall DLLStart(void) {
auto *thread = new AppThread(argc, argv);
thread->start();
return 0;
}
extern "C" void __stdcall DLLStop(void) {
delete qApp->thread();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.