2011-01-07 6 views
9

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

http://www.gevent.org/ - greeneletを使用してlibeventイベントループの最上位に同期APIを提供するcoroutineベースのPythonネットワーキングライブラリ。

+0

"gevent"とは何ですか?あなたの質問へのリンクを追加してください。 –

+0

http://www.gevent.org/ - greenletを使用してlibeventイベントループの最上位に同期APIを提供するcoroutineベースのPythonネットワーキングライブラリ。 –

+0

非常に興味深い.. pyqt + geventが動作するときに何をしますか? – linjunhalida

答えて

2

は、ここであなたが協力する例のセッション1でPyQtはをどのように変化するかです:https://github.com/traviscline/pyqt-by-example/commit/b5d6c61daaa4d2321efe89679b1687e85892460a

+2

0より大きい 'gevent.sleep'期間を使用していないので、何の役にも立たずに100%のCPU負荷に簡単につながります。 – fviktor

+0

グリーンレットでQtイベントループを実行するとうまく動作せず、セグフルトが発生し、モーダルダイアログが開いたときにブロックされます。 – mguijarr

4

あなたは、何のQtのイベントは時間の短い期間のために扱わない間にそのマイクロスレッドを処理するためgeventを可能にするためのQt IDLE「タイマー」を使用することができます例10ミリ秒。それは "スムーズな"可能な統合を提供しないので、まだ完璧ではありません。これは、Qtとgeventの両方に単一のイベントループを使用せず、時間内に単にインターリーブするためです。

正しい解決策は、libeventが新しいQtイベントを何とか聞くことができるようにすることですが、実際にはそれをどうやって行うのかまだ分かりません。 GUIイベントがイベントキューに到着したときにソケット経由で何かを送るために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() 
1

私はeventlet-pyqtという名前のプロジェクトを発表しました。 PyQtアプリケーションでグリーンレットを使いたい方には便利だと思います。私もgeventを試しましたが、C言語の貧弱な経験のためにlibevent用のプラグインを書くのは難しかったです。 QApplicaton::processEvents()またはゼロ間隔QTimerを使用する主な問題は、プログラムが無限ループに陥ってCPUコアが100%使用されることです。これを避けるため、select()関数をPyQtのQSocketNotifierに置き換える新しいハブを作成しました。このメッセージが何かを助けてくれることを願っています。

2

私は以下のアプローチを試しました:geventのための "PyQtバックエンド"を持っている、つまり。 libevループの代わりにQSocketNotifier、QTimerなどのようなPyQt構造を使用するgeventループの実装です。最後に、逆の作業よりもずっと簡単であり、パフォーマンスは非常に良いです(QtのループはLinuxのglibに基づいていますが、それほど悪くはありません)。ここで

は、興味のある人のためのgithubの上のプロジェクトへのリンクです: https://github.com/mguijarr/qtgevent

これは単なるスタートですが、それは私がやったテストに適しています。 geventとPyQtの経験が豊富な人が貢献できれば幸いです。

+0

これは、私のために働いています。 – Lepi

関連する問題