質問
Geventでpyqtを使用した人はいますか? PyqtループをGeventにリンクする方法は?
http://www.gevent.org/ - グリーンレットを使用して、Libeventイベントループの上に高レベルの同期APIを提供するCoroutineベースのPythonネットワーキングライブラリ。
解決
協力するために、ExampleのSession1によってPYQTを変更する方法は次のとおりです。 https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a
他のヒント
QTアイドル「タイマー」を使用して許可することができます gevent
たとえば、10ミリ秒など、短期間のQTイベントが処理されていない間、マイクロスレッドを処理するため。 「最もスムーズな」可能な統合を与えないため、まだ完璧ではありません。それは、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でより多くの経験を持つ人々が貢献できるなら、私は幸せです。
app.exec_()の使用を避ける必要があります。これは、この関数を使用してイベントを処理するループ関数です。
http://doc.qt.nokia.com/stable/qcoreapplication.html#processevents
したがって、ProcessEventsを直接呼び出すことができます。
名前のプロジェクトをリリースしました Eventlet-Pyqt. 。 PyqtアプリケーションでGreenletを使用したい人に役立つことを願っています。また、Geventを試しましたが、C言語の経験が悪いため、Libeventのプラグインを書くことは困難でした。使用の主な問題 QApplicaton::processEvents()
またはゼロインターバル QTimer
は、プログラムが無限ループに遭遇し、100%CPUコアの使用を引き起こします。これを避けるために、私は新しいハブを書きました select()
Pyqtの機能 QSocketNotifier
. 。このメッセージが誰かを助けることができることを願っています。