2016-03-02 56 views
0

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

问题

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

我的想法

我已经选中我不需要主QEventLoop,这是正常的,使一个又一个公正的网络(即嵌套)。不幸的是,我不知道如何并行运行两个循环,因为我的程序停在嵌套 - .exec(),所以主程序也停止。

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

+0

@KubaOber是的,你是完全正确的。如果您将此作为答案,我会将其标记为解决方案。 – user3085931

回答

1

主程序是否互动?如果是,那么它可能运行glib主事件循环。 Qt在Linux上使用相同的事件循环,因此您不需要在代码中调用exec()。通过创建一个QEventLoop的实例,向其发布退出调用,以及exec()这个事件循环,仅填充一次事件循环。然后将控制返回到主程序。当事件到达时(计时器超时,网络数据包到达等),您的代码仍然会运行。

您使用Qt获得的关于本地事件循环集成的奇妙之处在于,如果其他人已经在旋转循环,则不需要执行主要的exec()

所以,这里的Qt的插件Linux上的GTK应用程序如何可能看起来像:

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

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

一旦插件用户来电pluginInit,他们可以调用你的插件使用Qt的任何功能,且事件将被调用应用程序的事件循环正确处理。

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

如果线程对你来说不稳定,那么你做得不对。网络支持将在专用线程上运行良好。这可能是第二个线程的少数合法用途之一,因为这样您的网络数据处理不会因为用户场景渲染器和合成器将屏幕上显示的内容放在一起所花的甜蜜时间而延迟。

+0

工程像魅力。我从来没有想过使用'invokeMethod(...)'。非常感谢你 – user3085931

2

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

+0

是否可以保证我的输入连接将被接受(通过信号/插槽过程),还是可能因为线程当时没有运行而导致请求丢失? – user3085931

+1

您必须确保线程正在运行。如果线程没有运行,线程中的对象'生存'将不会被触发。出于这个原因,你应该创建线程,将对象移动到线程并启动线程。然后你可以建立你的连接。 – Paraboloid87