2012-04-06 71 views
1

我想学习如何在python程序中使用线程。我正在使用PySide和QThreads,因为我将在之后使用PySide实现gui。如何让QThreads在PySide程序的控制台中工作?

我已经理解了线程的主要概念,至少我认为。但是我仍然对事件循环感到困惑。我认为这是我的应用问题。

这是一个示例应用程序,我无法正常工作。 在我的主类中,我有几个工作线程,我希望他们向主要主类报告进度。但主程序不会实时打印进度信息。

我怎么能得到这个工作?

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_()) 
+0

你怎么在实时是什么意思?你必须在调用'wait()'之前启动所有线程。你开始一个,等待它完成,然后开始下一个。 – Dikei 2012-04-06 13:37:46

+0

该程序在工作循环中不会打印任何内容。但是它会在两个线程完成后同时打印所有消息。在此之后,该程序不会自行关闭。我将有几百名这些工人,他们的流程非常密集。所以实际上我甚至不希望那些在这一点上平行运行。也许以后我会改变这一点,所以很少有线程并行运行。 – LauriK 2012-04-06 14:00:04

+0

查看avaris的回答 – Dikei 2012-04-06 14:01:24

回答

5

worker.wait()是问题所在。这个调用阻塞了主线程(在这个例子中是一个正在运行的事件循环)直到工作完成。

这里有一个稍微改变版本(我的评论我的变化):

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_()) 
+0

谢谢,这是一个很大的帮助。 – LauriK 2012-04-06 14:37:00

相关问题