Question

Est-ce que quelqu'un utilise PyQt avec gevent? Comment lier boucle PyQt au gevent?

http://www.gevent.org/ - bibliothèque réseau Python basée coroutine qui utilise Greenlet à fournir une API synchrone de haut niveau sur le dessus de la boucle d'événement libevent.

Était-ce utile?

La solution

Voici comment vous changeriez pyqt par le session1 par exemple à coopérer: https: // github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a

Autres conseils

Vous pouvez utiliser un « timer » IDLE Qt pour permettre gevent pour le traitement de ses microfiletages en aucun événement Qt pour une période manutentionnés peu de temps, par exemple 10 millisecondes. Il est pas encore parfait, car il ne donne pas le « lisse » intégration possible. Il est parce que nous n'utilisons une seule boucle d'événement pour les Qt et gevent, juste « imbriquer » les temps.

La bonne solution serait de permettre libevent d'écouter les nouveaux événements Qt en quelque sorte, mais je n'ai pas été en mesure de savoir comment faire encore dans la pratique. Peut-être avoir Qt envoyer quelque chose à gevent via une prise lorsqu'un événement GUI arrive dans la file d'attente événement serait utile. Quelqu'un at-il résolu cela?

Exemple de travail:

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

J'ai essayé l'approche suivante: avoir un « back-end PyQt » pour gevent, à savoir. une mise en œuvre de la boucle gevent faisant usage de constructions PyQt comme QSocketNotifier, QTimer, etc. au lieu de la boucle de libev. Enfin je l'ai trouvé beaucoup plus facile que de faire le contraire, et la performance est très bonne (la boucle de Qt est basé sur le glib sous Linux, il est pas si mal).

Voici le lien vers le projet sur GitHub pour les personnes intéressées: https://github.com/mguijarr/qtgevent

Ceci est juste un début, mais il fonctionne bien pour les tests que j'ai fait. Je serais heureux si les gens avec plus d'expérience avec gevent et PyQt pourraient contribuer.

sould éviter l'utilisation app.exec_ (), il est une fonction de boucle qui utilisent cette fonction pour des événements de processus:

http://doc.qt.nokia.com/stable/qcoreapplication. html # processEvents

de sorte que vous pouvez appeler directement processEvents.

Je publié un projet nommé eventlet-pyqt . J'espère que cela pourrait être utile pour celui qui veut utiliser Greenlet dans leur application PyQt. J'ai aussi essayé gevent, mais il était difficile pour moi d'écrire un plugin pour libevent à cause de ma mauvaise expérience en langage C. Le principal problème en utilisant QApplicaton::processEvents() ou un QTimer zéro intervalle est, le programme de fonctionner en boucle infinie, provoque l'utilisation du noyau de CPU à 100%. Pour éviter cela, je l'ai écrit un nouveau centre pour remplacer la fonction select() avec QSocketNotifier PyQt. Espérons que ce message pourrait aider quelqu'un.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top