0

我尝试扩展一个在 Ubuntu/Linux 桌面下运行并支持 Qt 网络的旧程序。与这些库进行 LAN 通信需要运行.exec()QEventLoop 才能真正开始工作(即:接受连接、接收、发送等)

问题

问题是我不知道这个事件循环在主程序中的什么位置,而且因为我隐约知道它的设计,所以我更喜欢尽可能独立的解决方案。

我的点子

我已经检查过我不需要 main-QEventLoop,并且可以为网络(即嵌套)制作另一个。不幸的是,我不知道如何并行运行两个循环,因为我的程序在嵌套处停止.exec(),因此主程序也停止了。

所以我的主要意图实际上是用 Qt-Networking 扩展主程序,我也对其他解决方案持开放态度。

4

2 回答 2

2

如果您需要运行 2 个独立的事件循环,我建议使用 QThread。

于 2016-03-02T10:54:55.493 回答
1

主程序是交互式的吗?如果是,那么它很可能会运行 glib 主事件循环。Qt 在 Linux 上使用相同的事件循环,因此您无需exec()在代码中调用。QEventLoop通过创建 的实例、向其发布退出调用并对其进行调用,仅启动一次事件循环exec()。然后将控制权交还给主程序。您的代码仍将在事件到达时运行(计时器超时、网络数据包到达等)。

exec()使用 Qt 获得的本机事件循环集成的美妙之处在于,如果其他人已经在旋转循环,则无需执行 main 。

所以,下面是 Linux 上 GTK 应用程序的 Qt 插件的样子:

extern "C" void pluginInit() {
  new QApplication;
  QEventLoop loop;
  QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
  loop.exec();
}

extern "C" void pluginDestroy() {
  delete qApp;
}

一旦插件用户调用pluginInit,他们可以调用插件中使用 Qt 的任何函数,并且事件将由调用应用程序的事件循环正确处理。

与线程相比,我更喜欢这样的解决方案,因为它通常听起来更稳定。

如果线程对您来说不稳定,那么您做的不对。网络支持将在专用线程上运行良好。它可能是第二个线程为数不多的合法用途之一,因为这样您的网络数据处理就不会因为用户级渲染器和合成器将您在屏幕上看到的内容放在一起而延迟。

于 2016-03-11T14:34:02.863 回答