2009-05-01 15 views
2

私はPyQtプログラムを持っています。このプログラムでは、複雑な画像を描画するための新しいスレッドを開始します。 スレッドがいつ終了したかを知りたいので、フォームにイメージを印刷できます。Pythonでのスレッド終了イベント

私が直面している唯一の障害は、GUIスレッド内から描画する方法を呼び出す必要があることです。そのため、GUIスレッドに描画スレッド内から何かをさせる方法が必要です。

1つのスレッドを使用して実行できますが、プログラムは停止します。

私はC#で仕上げのためのイベントを持っているBackgroundWorkerを使っていました。

Pythonでこのようなことを行う方法はありますか?または私はPyQtアプリケーションのメインループをハックして少し変更する必要がありますか?

答えて

2

PyQt-Py2.6-gpl-4.4.4-2.exeのサンプルには、マンデルブロアプリがあります。私のインストールでは、ソースはC:\ Python26 \ Lib \ site-packages \ PyQt4 \ examples \ threads \ mandelbrot.pywにあります。これは、スレッドを使用して、pixmapと信号(QtCore.SIGNALのコードを検索)を描画して、GUIスレッドに描画時間を知らせます。あなたが望むもののように見えます。

0

あなたの描画スレッドはQApplication.postEventを使ってメインスレッドにイベントを送信できると思います。イベントの受信者としてオブジェクトを選択するだけです。 More info

0

Qt documentation on thread supportは、オブジェクトを「所有している」スレッドでイベントハンドラ(Qt用語ではスロット)を実行できると述べています。

あなたのケースでは、フォーム上にスロットprintImage(QImage)を定義し、画像を作成しているときにdoneDrawing(QImage)シグナルを定義し、キューまたは自動接続を使用して接続します。

1

私のプロジェクトで同様の問題が発生し、作業者の結果を表示してプログレスバーを更新するタイミングをメインGUIスレッドに伝えるために信号を使用しました。

PyQt reference guideにオブジェクトと信号を接続する例がいくつかあります。これらのすべてがPythonには適用されません(これを実現するにはしばらく時間がかかりました)。

ここでは、Pythonの信号をPython関数に接続するための例を示します。

QtCore.QObject.connect(a, QtCore.SIGNAL("PySig"), pyFunction) 
a.emit(QtCore.SIGNAL("pySig"), "Hello", "World") 

さらに、__pyqtSignals__ = ("PySig",)をワーカークラスに追加することを忘れないでください。ここで

は私がやったことのストリップダウンバージョンです:

class MyGui(QtGui.QMainWindow): 

    def __init__(self, parent=None): 
     QtGui.QMainWindow.__init__(self, parent) 
     self.worker = None 

    def makeWorker(self): 
     #create new thread 
     self.worker = Worker(work_to_do) 
     #connect thread to GUI function 
     QtCore.QObject.connect(self.worker, QtCore.SIGNAL('progressUpdated'), self.updateWorkerProgress) 
     QtCore.QObject.connect(self.worker, QtCore.SIGNAL('resultsReady'), self.updateResults) 
     #start thread 
     self.worker.start() 

    def updateResults(self): 
     results = self.worker.results 
     #display results in the GUI 

    def updateWorkerProgress(self, msg) 
     progress = self.worker.progress 
     #update progress bar and display msg in status bar 


class Worker(QtCore.QThread): 

    __pyqtSignals__ = ("resultsReady", 
         "progressUpdated") 

    def __init__(self, work_queue): 
     self.progress = 0 
     self.results = [] 
     self.work_queue = work_queue 
     QtCore.QThread.__init__(self, None) 

    def run(self): 
     #do whatever work 
     num_work_items = len(self.work_queue) 
     for i, work_item in enumerate(self.work_queue): 
      new_progress = int((float(i)/num_work_items)*100) 
      #emit signal only if progress has changed 
      if self.progress != new_progress: 
       self.progress = new_progress 
       self.emit(QtCore.SIGNAL("progressUpdated"), 'Working...') 
      #process work item and update results 
      result = processWorkItem(work_item) 
      self.results.append(result) 
     self.emit(QtCore.SIGNAL("resultsReady")) 
関連する問題