将 PyQt 与 gevent 结合使用
有人使用 PyQt 和 gevent 吗? 如何将 PyQt 循环链接到 gevent?
http://www.gevent.org/ - 基于协程的 Python 网络库,使用 greenlet 提供高性能libevent 事件循环之上的级同步 API。
Does anyone used PyQt with gevent?
How to link PyQt loop to the gevent?
http://www.gevent.org/ - coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of libevent event loop.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我发布了一个名为 eventlet-pyqt 的项目。我希望它对想要在 PyQt 应用程序中使用 greenlet 的人有用。我也尝试过gevent,但是由于我的C语言经验很差,给libevent写一个插件对我来说很困难。使用 QApplicaton::processEvents() 或零间隔 QTimer 的主要问题是,程序陷入无限循环,导致 CPU 核心使用率达到 100%。为了避免这种情况,我编写了一个新的集线器,用 PyQt 的
QSocketNotifier
替换select()
函数。希望此消息可以对某人有所帮助。I released a project named eventlet-pyqt. I hope it could be useful for the one who want to use greenlet in their PyQt application. I also tried gevent, but it was difficult for me to write a plugin for libevent because of my poor C language experience. The main problem using
QApplicaton::processEvents()
or a zero-intervalQTimer
is, the program run into infinite loop, causes 100% CPU core usage. To avoid this, I wrote a new hub to replace theselect()
function with PyQt'sQSocketNotifier
. Hope this message could help some one.您可以使用 Qt IDLE“计时器”来允许 gevent 处理其微线程,同时在短时间内(例如 10 毫秒)不处理 Qt 事件。它仍然不完美,因为它没有提供“最平滑”的可能集成。这是因为我们没有对 Qt 和 gevent 使用单个事件循环,只是及时“交错”它们。
正确的解决方案是允许 libevent 以某种方式监听新的 Qt 事件,但我还无法弄清楚如何在实践中做到这一点。也许当 GUI 事件到达事件队列时让 Qt 通过套接字向 gevent 发送一些内容会有所帮助。有人解决了吗?
工作示例:
You can use a Qt IDLE "timer" to allow
gevent
for processing its microthreads while no Qt events handled for a short period of time, for example 10 milliseconds. It is still not perfect, since it does not give the "smoothest" possible integration. It is because we don't use a single event loop for both Qt and gevent, just "interleaving" them in time.The correct solution would be to allow libevent to listen on new Qt events somehow, but I haven't been able to figure out how to do that in practice yet. Maybe having Qt to send something to gevent via a socket when a GUI event arrives into the event queue would help. Has anybody solved that?
Working example:
我尝试了以下方法:为 gevent 设置一个“PyQt 后端”,即。 gevent 循环的实现,使用 QSocketNotifier、QTimer 等 PyQt 结构,而不是 libev 循环。最后我发现它比做相反的事情容易得多,而且性能非常好(Qt的循环是基于Linux下的glib,还不错)。
对于感兴趣的人来说,这是 github 上该项目的链接:
https://github.com/mguijarr/qtgevent
这只是一个开始,但它对于我做了测试。如果对 gevent 和 PyQt 有更多经验的人能够做出贡献,我会很高兴。
I tried the following approach: to have a "PyQt backend" for gevent, ie. an implementation of the gevent loop making use of PyQt constructs like QSocketNotifier, QTimer, etc. instead of the libev loop. Finally I found it much easier than doing the opposite, and performance is very good (Qt's loop is based on the glib under Linux, it's not so bad).
Here is the link to the project on github for those interested:
https://github.com/mguijarr/qtgevent
This is just a start, but it works well for the tests I did. I would be happy if people with more experience with gevent and PyQt could contribute.
以下是如何通过示例的 session1 更改 pyqt 以进行协作: https://github.com /traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a
Here's how you would change pyqt by example's session1 to cooperate: https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a
你应该避免使用app.exec_(),它是一个循环函数,使用此函数来处理事件:
http://doc.qt.nokia.com/stable/qcoreapplication.html#processEvents
这样你就可以直接调用processEvents。
you sould avoid use app.exec_(), it is a loop function which use this function to process events:
http://doc.qt.nokia.com/stable/qcoreapplication.html#processEvents
so you can call processEvents directly.