有没有什么办法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框架的主循环。
任何建议和解决方案(更好)的欢迎。
这是相当古老的问题,但对于那些谁正在阅读它,我想和大家分享我的代码是对的boost :: ASIO QAbstractEventDispatcher的实现。
所有你需要的是创造的QApplication之前添加以下行(通常是在main())。
QApplication::setEventDispatcher(new QAsioEventDispatcher(my_io_service));
这将导致,那io_service对象正在使用Qt应用程序一起运行在一个线程中无需额外的延迟和性能下降(如在调用io_service对象::民意调查()“不时”的解决方案)。
不幸的是,我的解决方案仅适用于POSIX系统,因为它使用ASIO :: POSIX :: stream_descriptor。 支持Windows可能需要完全不同的方法或非常相似 - 我真的不知道。
简单:建立一个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信号更多的控制。
如果我没有理解你的问题,你有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来传送回:
- 定义一个自定义的QEvent类型
- 订阅这个事件
- 使用事件后Qt的事件循环QCoreApplication ::事件后() 。
真正的整合主回路是可能的。 这只是一个很大的痛苦(我还没有真正尝试)。
在一个单独的线程运行io_service对象:: run()的可能是要走的路。