2024-04-27 13:24:42 发布
网友
有人用过PyQt和gevent吗? 如何将PyQt循环链接到gevent?在
http://www.gevent.org/-基于协同程序的Python网络库,它使用greenlet在libevent事件循环之上提供高级同步API。在
我尝试了以下方法:为gevent提供一个“PyQt后端”,即使用QSocketNotifier、QTimer等PyQt结构实现gevent循环,而不是libev循环。最后,我发现这比做相反的事情容易得多,而且性能也非常好(Qt的循环是基于Linux下的glib,还不错)。在
以下是github上项目的链接,供感兴趣的人使用: https://github.com/mguijarr/qtgevent
这只是一个开始,但对我做的测试来说效果很好。如果有更多gevent和PyQt经验的人能做出贡献,我会很高兴的。在
下面是如何通过示例的session1更改pyqt以进行协作:https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a
您可以使用Qt空闲“计时器”来允许gevent处理其微线程,而在短时间内(例如10毫秒)没有处理Qt事件。它仍然不是完美的,因为它不能提供“最平滑”的整合。这是因为我们没有对Qt和gevent使用单个事件循环,只是在时间上“交错”它们。在
gevent
正确的解决方案应该是允许libevent以某种方式监听新的Qt事件,但我还没有找到在实践中如何做到这一点。也许当GUI事件到达事件队列时,让Qt通过套接字向gevent发送一些内容会有所帮助。有人解决了吗?在
工作示例:
""" Qt - gevent event loop integration using a Qt IDLE timer """ import sys, itertools import PySide from PySide import QtCore, QtGui import gevent # Limit the IDLE handler's frequency while still allow for gevent # to trigger a microthread anytime IDLE_PERIOD = 0.01 class MainWindow(QtGui.QMainWindow): def __init__(self, application): QtGui.QMainWindow.__init__(self) self.application = application self.counter = itertools.count() self.resize(400, 100) self.setWindowTitle(u'Counting: -') self.button = QtGui.QPushButton(self) self.button.setText(u'Reset') self.button.clicked.connect(self.reset_counter) self.show() def counter_loop(self): while self.isVisible(): self.setWindowTitle(u'Counting: %d' % self.counter.next()) gevent.sleep(0.1) def reset_counter(self): self.counter = itertools.count() def run_application(self): # IDLE timer: on_idle is called whenever no Qt events left for processing self.timer = QtCore.QTimer() self.timer.timeout.connect(self.on_idle) self.timer.start(0) # Start counter gevent.spawn(self.counter_loop) # Start you application normally, but ensure that you stop the timer try: self.application.exec_() finally: self.timer.stop() def on_idle(self): # Cooperative yield, allow gevent to monitor file handles via libevent gevent.sleep(IDLE_PERIOD) def main(): application = QtGui.QApplication(sys.argv) main_window = MainWindow(application) main_window.run_application() if __name__ == '__main__': main()
我尝试了以下方法:为gevent提供一个“PyQt后端”,即使用QSocketNotifier、QTimer等PyQt结构实现gevent循环,而不是libev循环。最后,我发现这比做相反的事情容易得多,而且性能也非常好(Qt的循环是基于Linux下的glib,还不错)。在
以下是github上项目的链接,供感兴趣的人使用: https://github.com/mguijarr/qtgevent
这只是一个开始,但对我做的测试来说效果很好。如果有更多gevent和PyQt经验的人能做出贡献,我会很高兴的。在
下面是如何通过示例的session1更改pyqt以进行协作:https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a
您可以使用Qt空闲“计时器”来允许
gevent
处理其微线程,而在短时间内(例如10毫秒)没有处理Qt事件。它仍然不是完美的,因为它不能提供“最平滑”的整合。这是因为我们没有对Qt和gevent使用单个事件循环,只是在时间上“交错”它们。在正确的解决方案应该是允许libevent以某种方式监听新的Qt事件,但我还没有找到在实践中如何做到这一点。也许当GUI事件到达事件队列时,让Qt通过套接字向gevent发送一些内容会有所帮助。有人解决了吗?在
工作示例:
相关问题 更多 >
编程相关推荐