如何整合Boost.Asio的像的Qt4或GTK GUI框架主循环(How to integrate

2019-06-23 09:33发布

有没有什么办法Boost.Asio的用的Qt4(首选)或GTK主循环集成? GTK像API提供轮询(2),从而在技术上是应该是可能的。 Qt提供自己的网络层,但我更喜欢使用Boost.Asio的书面现有的代码。 我想他们没有使用额外的线程整合。

有没有任何参考如何为的Qt4(首选)或gtkmm的做到这一点?

谢谢。

编辑

我想clearify几件事,使答案更容易。 Qt和gtkmm的提供“选择像”的功能:

  • http://qt-project.org/doc/qt-5.0/qtcore/qsocketnotifier.html
  • http://www.gtkmm.org/docs/glibmm-2.4/docs/reference/html/group__MainLoop.html

所以,问题是,如何整合现有的“选择/轮询”为反应器Boost.Asio的io_service 。 今天,Boost.Asio的可以使用选择,kqueue的,epoll的,的/ dev / poll和iocp的反应堆/摄服务。 我想将它集成到GUI框架的主循环。

任何建议和解决方案(更好)的欢迎。

Answer 1:

这是相当古老的问题,但对于那些谁正在阅读它,我想和大家分享我的代码是对的boost :: ASIO QAbstractEventDispatcher的实现。

所有你需要的是创造的QApplication之前添加以下行(通常是在main())。

QApplication::setEventDispatcher(new QAsioEventDispatcher(my_io_service));

这将导致,那io_service对象正在使用Qt应用程序一起运行在一个线程中无需额外的延迟和性能下降(如在调用io_service对象::民意调查()“不时”的解决方案)。

不幸的是,我的解决方案仅适用于POSIX系统,因为它使用ASIO :: POSIX :: stream_descriptor。 支持Windows可能需要完全不同的方法或非常相似 - 我真的不知道。



Answer 2:

简单:建立一个QT插槽调用io_service::poll_one()属于GUI。 连接该插槽Qt的tick信号。

在深度:幸运的是Boost.Asio的设计得非常好。 有关于如何提供一个执行线程底层异步内部很多选择。 人们已经提用io_service::run() ,一个阻塞调用有许多缺点。

你只能从一个线程访问GUI部件。 外螺纹一般需要事件发布到GUI,如果他们想要做的任何突变部件。 这是非常相似的短耳是如何工作的。

天真的方法是只奉献一个线程(或计时器)运行io_service::run() ,并有短耳完成处理后的GUI信号。 这工作。

相反,你可以使用保证完成处理程序将只在执行的线程调用io_service调用者。 没有GUI线程调用io_service::run() ,因为它是阻止和都挺图形用户界面。 而是使用io_service::poll()io_service::poll_one() 这将导致任何未决的短耳完成处理从GUI线程调用。 由于处理程序的GUI线程运行,他们可以自由地修改窗口小部件。

现在,你需要确保io_service都将有机会定期运行。 我建议具有重复GUI信号呼叫poll_one()几次。 我相信,QT有一个勾信号,会做的伎俩。 当然,你可以滚你自己QT信号更多的控制。



Answer 3:

如果我没有理解你的问题,你有Boost.Asio的编写的代码。 你想用一个GUI应用程序中的代码。

如果您想通过asynio包裹了Qt / GTK的网络层为您的代码的工作,如果你只是寻找一个既具有GUI事件循环的解决方案和asynio在一起,究竟是不是在你的问题是清楚的。

我将承担的第二种情况。

Qt和基于GTK有方法来整合他们的事件循环涉外事件。 例如见qtgtk在Qt的事件循环插入的Gtk。

在Qt的特定情况下,如果你想生成Qt的事件,您可以使用下面的类: QAbstractEventDispatcher 。

快速浏览一下提升ASIO后,我认为你需要做到以下几点:

  • 与持续时间为零的定期QTimer调用io_service对象:: run()的所有的时间。 为您的异步操作完成这样一来,升压:: ASIO会尽快打电话给你完成处理。
  • 在你完成处理,有两个选项:
    • 如果你完成操作是漫长的,从GUI中分离,做您的业务,并确保调用qApp.processEvents()经常保持GUI响应
    • 如果你只是想GUI来传送回:
      1. 定义一个自定义的QEvent类型
      2. 订阅这个事件
      3. 使用事件后Qt的事件循环QCoreApplication ::事件后() 。


Answer 4:

真正的整合主回路可能的。 这只是一个很大的痛苦(我还没有真正尝试)。

在一个单独的线程运行io_service对象:: run()的可能是要走的路。



文章来源: How to integrate Boost.Asio main loop in GUI framework like Qt4 or GTK