2011-01-07 17 views
9

¿Alguien usó PyQt con gevent? Cómo vincular PyQt loop al gevent?Uso de PyQt con gevent

http://www.gevent.org/ - biblioteca de red Python basada en coroutine que usa greenlet para proporcionar una API síncrona de alto nivel en la parte superior del ciclo de evento libevent.

+0

¿Qué es "gevent"? Por favor agregue enlaces a su pregunta. –

+0

http://www.gevent.org/ - biblioteca de redes de Python basada en coroutine que usa greenlet para proporcionar una API síncrona de alto nivel en la parte superior del ciclo de evento libevent. –

+0

muy interesante ... ¿qué harás cuando pyqt + gevent funcione? – linjunhalida

Respuesta

2

Así es como tendría que cambiar pyqt por session1 de ejemplo para cooperar: https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a

+2

Puede conducir fácilmente al 100% de carga de la CPU sin ninguna actividad útil, ya que no está utilizando un período 'gevent.sleep' mayor que cero. – fviktor

+0

Ejecutar el ciclo de eventos Qt en un punto verde no funciona bien, experimenté fallas seg y bloquea cuando se abre un cuadro de diálogo modal. – mguijarr

4

Puede utilizar un IDLE "temporizador" Qt para permitir gevent para el procesamiento de sus microfiletes mientras hay eventos Qt manejados por un corto período de tiempo, por ejemplo 10 milisegundos. Todavía no es perfecto, ya que no brinda la integración más "suave" posible. Es porque no usamos un solo ciclo de eventos para Qt y gevent, simplemente "intercalando" a tiempo.

La solución correcta sería permitir que libevent escuche los nuevos eventos de Qt de alguna manera, pero todavía no he podido descifrar cómo hacerlo en la práctica. Tal vez tener Qt para enviar algo a gevent a través de un socket cuando un evento GUI llegue a la cola del evento ayudaría. ¿Alguien ha resuelto eso?

Ejemplo de trabajo:

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

me dio a conocer un proyecto llamado eventlet-pyqt. Espero que pueda ser útil para quien quiera usar greenlet en su aplicación PyQt. También probé gevent, pero me resultó difícil escribir un plugin para libevent debido a mi pobre experiencia en el lenguaje C. El problema principal al usar QApplicaton::processEvents() o un intervalo cero QTimer es que el programa se ejecuta en un bucle infinito y causa un uso del núcleo del 100% de la CPU. Para evitar esto, escribí un nuevo concentrador para reemplazar la función select() con PyQt's QSocketNotifier. Espero que este mensaje pueda ayudar a alguien.

2

He intentado el siguiente enfoque: tener un "backend PyQt" para gevent, es decir. una implementación del ciclo gevent haciendo uso de construcciones PyQt como QSocketNotifier, QTimer, etc. en lugar del ciclo libev. Finalmente me pareció mucho más fácil que hacer lo opuesto, y el rendimiento es muy bueno (el ciclo de Qt se basa en el glib bajo Linux, no es tan malo).

Aquí está el enlace al proyecto en GitHub para los interesados: https://github.com/mguijarr/qtgevent

Esto es sólo un comienzo, pero funciona bien para las pruebas que hice. Sería feliz si las personas con más experiencia con gevent y PyQt pudieran contribuir.

+0

Esto me funciona de la caja, gracias hombre! – Lepi