Вопрос

Кто-нибудь использовал PYQT с Gevent? Как связать петлю PYQT к Gevent?

http://www.gevent.org/ - Библиотека сети Python на основе COROUTINE, которая использует Greenlet для обеспечения синхронного API высокого уровня в верхней части Libevent Coop.

Это было полезно?

Решение

Вот как вы бы изменили PYQT на примере Session1 для сотрудничества: https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a.

Другие советы

Вы можете использовать таймер Qt Widle ", чтобы разрешить gevent Для обработки своих микротикров, в то время как события QT не обрабатываются в течение короткого периода времени, например, 10 миллисекунд. Это все еще не идеально, так как он не дает «гладкой» возможной интеграции. Это потому, что мы не используем единый цикл событий как для Qt, так и Gevent, просто «чередование» их во времени.

Правильное решение было бы разрешено как-то как-то слушать новые события QT, но я еще не смог выяснить, как это сделать на практике. Может быть, имея Qt для отправки чего-то в Gevent через сокет, когда событие GUI поступает в очередь события, поможет. Кто-нибудь решил это?

Рабочий пример:

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

Я попробовал следующий подход: иметь «Backend Pyqt» для Gevent, то есть. Реализация петли Gevent, использующая конструкции PYQT, таких как QSocketnotifier, QTimer и т. Д. Вместо цикла Libev. Наконец, я нашел его намного проще, чем выполнение противоположного, а производительность очень хорошая (цикл Qt основан на Glib под Linux, это не так плохо).

Вот ссылка на проект на Github для тех, кто заинтересован:https://github.com/mguijarr/qtgevent.

Это всего лишь начать, но хорошо работает для испытаний, которые я сделал. Я был бы счастлив, если бы люди с большим опытом с Gevent и Pyqt могут внести свой вклад.

Вы не должны использовать app.exec_ (), это функция петли, которая использует эту функцию для обработки событий:

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

Таким образом, вы можете позвонить процессам напрямую.

Я выпустил проект по имени Eventlet-Pyqt.. Отказ Я надеюсь, что это может быть полезно для того, кто хочет использовать Greenlet в своем приложении PYQT. Я также попробовал Gevent, но мне было трудно написать плагин для либерента из-за моего бедного языка C. Основная проблема с использованием QApplicaton::processEvents() или нулевой интервал QTimer Есть, программа работает в бесконечный цикл, вызывает 100% одноъядерное использование CPU. Чтобы избежать этого, я написал новый концентратор, чтобы заменить select() Функция с pyqt QSocketNotifier. Отказ Надеюсь, что это сообщение может помочь кому-нибудь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top