如何将Qt嵌入到另一个应用程序中(非阻塞方式)

How to have Qt embedded into another app (non-blocking way)

本文关键字:方式 应用程序 另一个 Qt      更新时间:2023-10-16

我正在使用一个3D渲染C++API,并希望使用Qt在其顶部显示GUI。

我的渲染API运行在main()应用程序线程中,就像Qt想要的那样。

起初,我试图在Qt自己的std::线程中运行它,它运行得非常好——我不知道Qt的文档对意味着什么

如前所述,每个程序启动时都有一个线程。这线程被称为"主线程"(在Qt应用程序)。Qt GUI必须在此线程中运行https://doc.qt.io/qt-5/thread-basics.html

这要么是完全错误的,要么写得不好。。。

我的std::线程工作者看起来像这样:

int SomeClass::qt_app_worker(size_t width, size_t height, const std::string& title, const std::string& contents) {
int argc = 0;
QApplication app(argc, NULL);
// QDialog here
return app.exec();
}

问题是,我不能用这个Qt应用程序做任何事情,因为如果我试图从main()线程创建另一个QDialog,Qt会抱怨我只能从拥有我的QApplication(Qt_app_worker)的线程中创建。

因此,我要么被永久地锁定在qt_app_worker线程之外,要么我必须为所有与qt相关的事情实现我自己的消息队列。

我用一个派生的QApplication类绘制了它的草图,使用startTimer(),然后在timerEvent(…)中处理自定义消息,但这太麻烦了。

我只是不明白为什么Qt不让用户在一个单独的线程中运行它,希望我只是错过了一些东西。

至少有两种内置的线程安全方式可以与GUI线程(通常是Qt应用程序的"主线程",这就是为什么它经常被称为主线程,从Qt的角度来看也是如此)进行通信。

  • 您可以使用QCoreApplication::postEvent将事件(包括您自己的自定义事件子类)发布到线程
  • 您可以调用另一个线程中对象的方法,前提是使用QMetaObject::invokeMethod(及其不同的重载)使用Qt::QueuedConnectionQt::BlockingQueuedConnection连接类型

从Qt到您自己的主线程的另一种通信方式有几种。我相信使用Qt::BlockingQueuedConnection也可以获得一个返回值,但您可能不希望这种阻塞。。。。因此,您可以使用任何常见的线程间通信方法,而不受Qt的限制,例如从Qt设置的原子或互斥保护变量,并且您的线程在相关时(例如在每帧开始时)进行轮询或以其他方式读取。或者制作一个简单的消息队列,如果您希望能够跟踪每一个更改,而不仅仅是帧开始时的状态或其他什么。

相关文章: