1

Pythonプログラムでスレッドを使用する方法を学ぼうとしています。後でPySideでGUIを実装するので、PySideとQThreadsを使用しています。

私は、少なくとも私が思うに、糸脱毛の主な概念を理解しました。しかし、私はまだイベントループと混同しています。そして、それが私のアプリケーションの問題だと思います。

これは私が正しく動作させることができないサンプルアプリケーションです。私のメインクラスにはいくつかのワーカースレッドがあり、それらのスレッドをメインメインクラスに報告してもらいたいと思います。ただし、メインプログラムは進行状況メッセージをリアルタイムで出力しません。

どうすればこれを機能させることができますか?

from PySide import QtCore
import time, sys

class MyWorkerThread(QtCore.QThread):
    message = QtCore.Signal(str)

    def __init__(self, id, parent=None):
        super(MyWorkerThread, self).__init__(parent)
        self.id = id

    def run(self):
        for i in range(10):
            self.message.emit("%d: %d" % (self.id, i))
            time.sleep(0.2)

class MainProgram():
    def __init__(self, parent=None):
        self.threads = []

        self.addWorker(MyWorkerThread(1))
        self.addWorker(MyWorkerThread(2))

    def addWorker(self, worker):
        worker.message.connect(self.printMessage, QtCore.Qt.QueuedConnection)
        self.threads.append(worker)

    def startWorkers(self):
        for worker in self.threads:
            worker.start()
            worker.wait()
        self.workersFinished()

    def workersFinished(self):
        QtCore.QCoreApplication.instance().quit()

    @QtCore.Slot(str)
    def printMessage(self, text):
        sys.stdout.write(text+'\n')
        sys.stdout.flush()

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    m = MainProgram()
    m.startWorkers()
    sys.exit(app.exec_())
4

1 に答える 1

5

worker.wait()問題です。この呼び出しは、ワーカーがジョブを終了するまで、メインスレッド(この場合は1つの実行中のイベントループ)をブロックします。

これが少し変更されたバージョンです(私は自分の変更にコメントしました):

from PySide import QtCore
import time, sys

class MyWorkerThread(QtCore.QThread):
    message = QtCore.Signal(str)

    def __init__(self, id, parent=None):
        super(MyWorkerThread, self).__init__(parent)
        self.id = id

    def run(self):
        for i in range(10):
            self.message.emit("%d: %d" % (self.id, i))
            time.sleep(0.2)

class MainProgram():
    def __init__(self, parent=None):
        self.threads = []

        self.addWorker(MyWorkerThread(1))
        self.addWorker(MyWorkerThread(2))

    def addWorker(self, worker):
        worker.message.connect(self.printMessage, QtCore.Qt.QueuedConnection)
        # connect the finished signal to method so that we are notified
        worker.finished.connect(self.workersFinished)
        self.threads.append(worker)

    def startWorkers(self):
        for worker in self.threads:
            worker.start()
            # no wait, no finished. you start the threads and leave.

    def workersFinished(self):
        if all(worker.isFinished() for worker in self.threads):
            # wait until all the threads finished
            QtCore.QCoreApplication.instance().quit()

    @QtCore.Slot(str)
    def printMessage(self, text):
        sys.stdout.write(text+'\n')
        sys.stdout.flush()

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    m = MainProgram()
    m.startWorkers()
    sys.exit(app.exec_())
于 2012-04-06T13:51:28.997 に答える