2011-01-07 27 views
9

有沒有人使用PyQt和gevent? 如何將PyQt循環鏈接到gevent?在gevent中使用PyQt

http://www.gevent.org/ - 基於協同程序的Python網絡庫,它使用greenlet在libevent事件循環之上提供高級同步API。

+0

什麼是「gevent」?請添加您的問題的鏈接。 – 2011-01-07 17:28:09

+0

http://www.gevent.org/ - 基於coroutine的Python網絡庫,它使用greenlet在libevent事件循環之上提供高級同步API。 – 2011-01-09 15:47:31

+0

非常有趣..當pyqt + gevent工作時你會做什麼? – linjunhalida 2011-01-17 07:32:41

回答

4

您可以使用Qt的空閒「計時器」,讓gevent處理其微線程而沒有Qt的事件的短時間內進行處理,對例如10毫秒。它還不完美,因爲它沒有給出「最平滑」的可能整合。這是因爲我們不爲Qt和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() 
1

我發佈了一個名爲eventlet-pyqt項目。我希望對於想在他們的PyQt應用程序中使用greenlet的人有用。我也嘗試了gevent,但由於我的C語言經驗不足,我很難爲libevent編寫一個插件。使用QApplicaton::processEvents()或零間隔QTimer的主要問題是程序運行到無限循環,導致100%的CPU內核使用率。爲了避免這種情況,我寫了一個新的集線器,用PyQt的QSocketNotifier取代select()函數。希望這個消息可以幫助某個人。

2

我嘗試了以下方法:爲gevent創建一個「PyQt後端」,即。 gevent循環的實現使用PyQt構造,如QSocketNotifier,QTimer等,而不是libev循環。最後,我發現它比做相反的事情容易得多,而且性能非常好(Qt的循環是基於Linux下的glib,並不是那麼糟糕)。

這裏是鏈接到該項目在GitHub上對於那些有興趣: https://github.com/mguijarr/qtgevent

這僅僅是一個開始,但它很適合我做的測試。如果具有gevent和PyQt更多經驗的人可以貢獻,我會很高興。