首页 > 解决方案 > 带有 Qt 事件循环的便携式通用共享库设置

问题描述

我们正在尝试编写一个可移植的共享库,它使用一些 Qt 类来方便(主要QTimerQTcpSocket);不过,没有 GUI 的东西。相应的信号/插槽连接似乎需要一些 Qt 事件循环,因此我们按照此答案QCoreApplication中的概述“启动” a 。因此,我们设置了一个工作对象来完成繁重的工作并将其移动到.QThread

我们现在遇到的问题是QThread的所有者对象(在主线程内)和工作对象之间的排队连接QThread似乎永远不会在 Linux 系统上得到处理,至少只要实现我们的库的程序确实如此不在主线程中提供它自己的任何进一步的 Qt 事件循环。这不是很有帮助,因为从工作线程传递到主线程的数据应该使用一些回调函数进一步传递,但现在这些函数永远不会被调用。

因此,我的问题是:有没有办法让事件循环在库主线程中工作而不会锁定它或主机程序(这似乎只是放一个QCoreApplication::exec()或类似的情况)?或者我们是否必须建立不同的线程间通信方案(独立于 Qt)来处理这些数据传输?

由于我们不知道主机软件是否会在 a 上运行QApplication,因此理想情况下,我还会在设置主线程事件循环之前对其进行检查。是一个简单的if(qApp != nullptr)是否足够

PS:我尝试了一些但对我不起作用的东西:

标签: c++qtshared-librariesqt5platform-independent

解决方案


在 Qt 用语中,回调称为Qt::DirectConnection. 但当然,这些回调将在您的工作线程上运行。但是任何其他使用回调的库都是这种情况,因此 Qt 在这里不是问题,您的代码也不是:基本思想具有此属性。

如果宿主应用程序没有使用事件循环(任何事件循环,不一定是 Qt 的),那么除了轮询之外你无能为力——见下文。

如果宿主应用程序运行 X11 事件循环,那么您需要确保您的 Qt 副本使用与宿主应用程序相同的底层事件循环。通常,这将是 glib 的事件循环,然后它应该自动工作。否则,您需要将 Qt 事件循环使用的同步原语的文件描述符传递给用户,并且用户需要将其集成到他们的事件循环中。无论您是否使用 Qt,您都将面临同样的问题:滚动您自己的通信方法不会修复它,因为您仍然需要一个可与用户正在使用的任何事件循环互操作的可等待原语。

用户当然可以随时轮询回调:公开一个mainPoll()转发到QCoreApplication::processEvents().


推荐阅读