2012-11-29 163 views
2

我正在用GUI和几个工作线程构建一个应用程序。现在我希望它成为一个多线程应用程序,所以我多次执行相同的线程,在一个循环中,每个线程都抓取不同线程之外的类中定义的不同输入参数。线程退出后Qt处理信号?

所以我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控制台看到线程正在执行他们的任务,并且一旦他们正在做他们正在做的任何事情,表中突然填充了一堆数据。

正如您可能想象的那样,由此产生的另一个问题是,由于没有正在处理的事件,一段时间后,我的应用程序似乎被冻结。

我曾尝试将Qt.DirectConnection添加到connect()方法,但这并没有真正的帮助。

奖励问题:我一直在阅读关于SO和其他网站上的这个话题,似乎人们推荐QRunnable()而不是QThread(),尤其是当它涉及到子类。因此,我会使用QThreadPool()。但是,当我尝试这样做时,我似乎无法发出来自QRunnable的信号 - 即使信号是在QRunnable类中定义的,它也给我提供了AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect' - 这很奇怪,我必须说。

编辑:在另一个关于SO的回答中,有人提到可能会将具有要处理事件的主GUI线程“垃圾”。然而,我不认为这是这种情况,因为QThread中的sendToTable()方法最多只能从线程调用5-6次,并且threadCount最多不会超过20,但我通常将它保留在大约5.

+0

可能下次花更多时间研究? –

+2

谢谢,你非常有帮助。我花了2天时间对此进行调试。 –

回答

2

和往常一样,我在SO上发布2天调试和分钟后回答我的问题。

在所有线程启动后,我有一个剩余的workerThread.wait()方法调用。自然,我的应用程序完成了它被告知要做的事 - 等待线程完成。

我删除了该方法调用,并且还将QCoreApplication.processEvents()放入启动线程的循环中,现在它的所有功能都像魅力一样。

再一次,谢谢你,这个无形的,全能的人!

+1

那么,听说过“橡皮鸭调试/问题解决”?这里你去:http://www.codinghorror.com/blog/2012/03/rubber-duck-problem-solving.html –