GUIといくつかのワーカースレッドを使用してアプリケーションを構築しています。マルチスレッドアプリケーションにしたいので、同じスレッドをループで数回実行します。各スレッドは、スレッド外のクラスで定義された異なる入力パラメーターを取得します。
したがって、私のmainGui.pyファイルは次のようになります(関連するコードのみが表示されています)。
self.workers = [worker.Worker(), worker.Worker(), worker.Worker()]
for i in xrange(threadCount):
self.currentWorker = self.workers[i]
self.currentWorker.alterTable.connect(self.alterMainTable)
self.currentWorker.start()
time.sleep(0.1)
ご想像のとおり、私はワーカーのalterTable
信号をalterMainTable()
メインのGUIスレッドで定義したメソッドに接続しています。このメソッドは、GUIのテーブルを更新します。
ワーカースレッドは次のようになります。
class Worker(QThread):
alterTable = Signal(dict)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def sendToTable(self, param1, param2, param3):
"""This method emits the signal with params as defined above"""
params = {}
params["param1"] = param1
params["param2"] = param2
params["param3"] = param3
self.alterTable.emit(params)
def run(self):
#Perform a lengthy task, do this every now and then:
self.sendToTable(param, param2, param3)
このアプリケーションを単一のワーカースレッドで実行している場合(つまり、メインスレッドでそのループを呼び出していない場合)、正常に動作します。シグナルが発行され、GUIのメインテーブルが更新されます。
ただし、一度に複数のスレッドを実行すると問題が発生します。ワーカースレッドはその役割を果たしますが、シグナルはたまにしか発行されません。または、さらに良いことに、Qt(またはその他)がすべてのスレッドの終了を待っているかのように出力され、テーブルを更新します。これは文字通り何が起こるかです-Pythonコンソールで、スレッドがタスクを実行していることがわかります。すべてのスレッドが実行していることを実行すると、テーブルに突然大量のデータが一度に入力されます。
ご想像のとおり、これから生じるもう1つの問題は、処理中のイベントがないため、しばらくするとアプリケーションがフリーズしたように見えることです。
Qt.DirectConnection
メソッドにを追加しようとしましたconnect()
が、それは実際には役に立ちませんでした。
ボーナスの質問:私はSOや他のウェブサイトでこのトピックについて読んでいますがQRunnable()
、QThread()
特にサブクラス化する場合は、人々が推奨するのではないようです。したがって、私はを使用しQThreadPool()
ます。しかし、これを試したところ、-から信号を発することができないようです-SignalがQRunnableクラス内で定義されていても、QRunnable
-それは私に信号を与えます-これはかなり奇妙です、私は言わなければなりません。AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect'
編集:SOに関する別の回答で、誰かが、処理されるイベントでメインGUIスレッドを「スパム」している可能性があると述べました。sendToTable()
ただし、 QThreadのメソッドはスレッドから最大で5〜6回しか呼び出されず、threadCount
最大で20を超えることはないため、これが当てはまるとは思いませんが、通常は5前後に保ちます。 。