2011-01-07 14 views
9

Hat jemand PyQt mit gevent verwendet? Wie verknüpfe ich die PyQt-Schleife mit dem Gevent?Verwendung von PyQt mit gevent

http://www.gevent.org/ - Coroutine-basierte Python-Netzwerkbibliothek, die Greenlet verwendet, um eine High-Level-synchrone API zusätzlich zur Libevent-Ereignisschleife bereitzustellen.

+0

Was ist "gevent"? Bitte fügen Sie Links zu Ihrer Frage hinzu. –

+0

http://www.gevent.org/ - Coroutine-basierte Python-Netzwerkbibliothek, die Greenlet verwendet, um eine High-Level-synchrone API zusätzlich zur Libevent-Ereignisschleife bereitzustellen. –

+0

sehr interessant .. was machst du wenn pyqt + gevent funktioniert? – linjunhalida

Antwort

2

Hier ist, wie Sie pyqt mit gutem Beispiel des session1 ändern würde zu kooperieren: https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a

+2

Es kann leicht zu 100% CPU-Auslastung ohne sinnvolle Aktivität führen, da Sie keine 'gevent.sleep'-Periode größer als Null verwenden. – fviktor

+0

Das Ausführen der Qt-Ereignisschleife in einem Greenlet funktioniert nicht gut, ich habe Seg-Fehler festgestellt und blockiert, wenn ein modales Dialogfeld geöffnet wird. – mguijarr

4

Sie können eine Qt IDLE „Timer“ verwenden gevent zur Verarbeitung seiner Microthreads zu ermöglichen, während keine Qt Ereignisse für einen kurzen Zeitraum behandelt, für Beispiel 10 Millisekunden. Es ist immer noch nicht perfekt, da es nicht die "glatteste" mögliche Integration gibt. Das liegt daran, dass wir für Qt und Gevent keine einzige Ereignisschleife verwenden, sondern sie nur zeitlich verschachteln.

Die richtige Lösung wäre es, Libevent zu erlauben, auf neue Qt-Ereignisse irgendwie zu hören, aber ich bin noch nicht in der Lage, herauszufinden, wie man das in der Praxis macht. Vielleicht würde es hilfreich sein, wenn Qt über einen Socket etwas an gevent sendet, wenn ein GUI-Ereignis in der Ereigniswarteschlange eintrifft. Hat jemand das gelöst?

Arbeitsbeispiel:

""" 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

veröffentlichte ich ein Projekt mit dem Namen eventlet-pyqt. Ich hoffe, dass es für denjenigen nützlich sein könnte, der in seiner PyQt-Anwendung greenlet verwenden möchte. Ich habe auch versucht, gevent, aber es war schwierig für mich, ein Plugin für Libevent zu schreiben wegen meiner schlechten C-Spracherfahrung. Das Hauptproblem bei der Verwendung oder ein Null-Intervall QTimer ist, dass das Programm in Endlosschleife ausgeführt wird, verursacht 100% CPU-Kernnutzung. Um dies zu vermeiden, schrieb ich einen neuen Hub, der die select() Funktion durch PyQt QSocketNotifier ersetzt. Ich hoffe, diese Nachricht könnte jemandem helfen.

2

Ich habe den folgenden Ansatz versucht: ein "PyQt-Backend" für gevent zu haben, dh. eine Implementierung der gevent-Schleife, die PyQt-Konstrukte wie QSocketNotifier, QTimer usw. anstelle der libev-Schleife verwendet. Schließlich fand ich es viel einfacher als das Gegenteil, und die Leistung ist sehr gut (Qt's Loop basiert auf dem Glib unter Linux, es ist nicht so schlecht). Hier

ist der Link zu dem Projekt auf Github für Interessenten: https://github.com/mguijarr/qtgevent

Dies ist nur ein Anfang, aber es funktioniert gut für die Tests, die ich tat. Ich würde mich freuen, wenn Leute mit mehr Erfahrung mit Gevent und PyQt beitragen könnten.

+0

Dies funktioniert für mich aus der Box, danke Mann! – Lepi