9

誰かがgeventでPyQtを使用しましたか?PyQtループをgeventにリンクする方法は?

http://www.gevent.org/-コルーチンベースのPythonネットワークライブラリ。グリーンレットを使用して、libeventイベントループの上に高レベルの同期APIを提供します。

4

5 に答える 5

5

Qt IDLE「タイマー」を使用geventして、マイクロスレッドを処理できるようにすることができますが、Qtイベントは短時間(たとえば10ミリ秒)処理されません。それは「最もスムーズな」可能な統合を提供しないので、それはまだ完全ではありません。これは、Qtとgeventの両方に単一のイベントループを使用せず、時間内にそれらを「インターリーブ」するだけだからです。

正しい解決策は、libeventが新しいQtイベントを何らかの方法でリッスンできるようにすることですが、実際にそれを行う方法をまだ理解できていません。たぶん、GUIイベントがイベントキューに到着したときにソケットを介してgeventに何かを送信するQtがあると便利です。誰かがそれを解決しましたか?

実例:

""" 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()
于 2011-11-27T05:37:21.337 に答える
3

私は次のアプローチを試しました:gevent用の「PyQtバックエンド」を用意する。libevループの代わりにQSocketNotifier、QTimerなどのPyQtコンストラクトを使用するgeventループの実装。最後に、反対のことをするよりもはるかに簡単で、パフォーマンスは非常に優れていることがわかりました(QtのループはLinuxでのglibに基づいており、それほど悪くはありません)。

興味のある方のためのgithubのプロジェクトへのリンクは次のとおりです: https ://github.com/mguijarr/qtgevent

これはほんの始まりに過ぎませんが、私が行ったテストではうまく機能します。geventやPyQtの経験が豊富な人が貢献できたら嬉しいです。

于 2013-10-01T23:17:05.947 に答える
2

協力するために例のsession1によってpyqtを変更する方法は次のとおりです:https ://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a

于 2011-02-16T00:37:29.717 に答える
1

app.exec_()の使用は避けてください。これは、この関数を使用してイベントを処理するループ関数です。

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

したがって、processEventsを直接呼び出すことができます。

于 2011-01-17T07:36:37.647 に答える
1

eventlet-pyqtという名前のプロジェクトをリリースしました。PyQtアプリケーションでグリーンレットを使用したい人に役立つことを願っています。geventも試しましたが、C言語の経験が乏しいため、libeventのプラグインを作成するのは困難でした。QApplicaton::processEvents()またはゼロ間隔を使用する主な問題QTimerは、プログラムが無限ループに陥り、CPUコアの使用率が100%になることです。select()これを回避するために、関数をPyQtに置き換える新しいハブを作成しましたQSocketNotifier。このメッセージが誰かを助けることができることを願っています。

于 2013-08-27T14:48:55.073 に答える