誰かがgeventでPyQtを使用しましたか?PyQtループをgeventにリンクする方法は?
http://www.gevent.org/-コルーチンベースのPythonネットワークライブラリ。グリーンレットを使用して、libeventイベントループの上に高レベルの同期APIを提供します。
誰かがgeventでPyQtを使用しましたか?PyQtループをgeventにリンクする方法は?
http://www.gevent.org/-コルーチンベースのPythonネットワークライブラリ。グリーンレットを使用して、libeventイベントループの上に高レベルの同期APIを提供します。
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()
私は次のアプローチを試しました:gevent用の「PyQtバックエンド」を用意する。libevループの代わりにQSocketNotifier、QTimerなどのPyQtコンストラクトを使用するgeventループの実装。最後に、反対のことをするよりもはるかに簡単で、パフォーマンスは非常に優れていることがわかりました(QtのループはLinuxでのglibに基づいており、それほど悪くはありません)。
興味のある方のためのgithubのプロジェクトへのリンクは次のとおりです: https ://github.com/mguijarr/qtgevent
これはほんの始まりに過ぎませんが、私が行ったテストではうまく機能します。geventやPyQtの経験が豊富な人が貢献できたら嬉しいです。
協力するために例のsession1によってpyqtを変更する方法は次のとおりです:https ://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a
app.exec_()の使用は避けてください。これは、この関数を使用してイベントを処理するループ関数です。
http://doc.qt.nokia.com/stable/qcoreapplication.html#processEvents
したがって、processEventsを直接呼び出すことができます。
eventlet-pyqtという名前のプロジェクトをリリースしました。PyQtアプリケーションでグリーンレットを使用したい人に役立つことを願っています。geventも試しましたが、C言語の経験が乏しいため、libeventのプラグインを作成するのは困難でした。QApplicaton::processEvents()
またはゼロ間隔を使用する主な問題QTimer
は、プログラムが無限ループに陥り、CPUコアの使用率が100%になることです。select()
これを回避するために、関数をPyQtに置き換える新しいハブを作成しましたQSocketNotifier
。このメッセージが誰かを助けることができることを願っています。