Windows消息循环而不是QApplication :: exec()/ QApplication :: processEvents()

Ter*_*man 12 c++ qt

Qt如果我QApplication::exec()用标准的Windows消息循环实现代替,我会错过任何功能吗?这应该澄清我的意思:

用于运行事件处理的因果"Qt"方式:

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 Window w;
 w.show();
 return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

"Windows"方式运行事件处理:

#include <Windows.h>

int main(int argc, char *argv[])
{
 QApplication a(argc, argv);
 Window w;
 w.show();

 MSG msg;
 while(GetMessage(&msg, 0, 0, 0)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
 }

 return msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)

上面演示了关于QApplication实例的外部消息循环,而QApplication实例本身甚至根本没有自己的事件循环.

换句话说,如果我有main.exe消息循环的程序(对Qt一无所知).dllQApplication内部的Qt GUI和实例,是否可以让外部消息循环main.exe来处理Qt GUI的事件?提前致谢!

编辑1: 我只是回答我自己的情况下,它是有用的人:我们有.NET下的C#编写的一个主要的.exe模块运行事件循环处理,我们有一对夫妇写的Qt/C++具有.DLL文件的GUI"内部"(以及共享的QApplication实例).永远不会调用QApplication :: exec(),但主.exe(.NET)模块的事件循环会成功调度所有事件,并且所有Qt函数都存在(信号/插槽,线程等)

编辑2: 这适用于Qt 4.8.2,但对于Qt 5.1.0,情况有点不同.现在你必须调用QApplication :: processEvents()一次,因为它在第一次调用时执行一些初始化初始化(在GetMessage或PeekMessage上安装WindowsHook).之后,无论谁在你的应用程序中调用GetMessage,Qt事件都会获得进程并且你是金色的:)

小智 1

我首先想到的是跨线程调用槽是行不通的,因为 Qt 事件循环正在执行这些调用。

但更重要的问题可能是:为什么你想这样做,特别是因为在 qeventdispatcher_win.cpp 中基本上做了同样的事情?

  • @Terenty Rezman在这种情况下,您可以定期调用 QCoreApplication::processEvents()。当您的 DLL 加载时,您可能还需要构造一个虚拟的 QApplication 或 QCoreApplication 对象。我已经有一段时间没有做过类似的事情了(在 MFC 应用程序中运行的 DLL 中的 Qt),但是当我这样做时大部分都有效。 (2认同)