我正在使用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)
正如您可能想象的那样,我将Worker的alterTable
信号连接到我在主GUI线程中定义的alterMainTable()
方法。此方法更新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中的主表。 / p>
但是,当我一次运行多个线程时会出现问题。工作线程完成它们的工作,但信号仅在有时发出。或者,更好的是,它被释放,好像Qt(或其他)等待所有线程完成,然后更新表。这就是发生了什么 - 我可以在Python控制台中看到线程正在执行他们的任务,一旦所有他们正在做他们正在做的任何事情,表突然填充了一堆数据at一旦。
正如您可能想象的那样,另外一个问题是,由于没有事件被处理,经过一段时间后,我的应用程序似乎被冻结了。
我尝试将Qt.DirectConnection
添加到connect()
方法,但这并没有真正帮助。
奖金问题:我在SO和其他网站上一直在阅读这个主题,似乎人们推荐QRunnable()
而不是QThread()
,特别是在进行子类化时。因此,我将使用QThreadPool()
。但是当我尝试这个时,似乎我无法从QRunnable
发出信号 - 它给了我AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect'
,即使信号是在QRunnable类中定义的 - 这很奇怪,我必须说。
编辑:在另一个关于SO的答案中,有人提到可能会在主要GUI线程中“发送垃圾邮件”并处理要处理的事件。但是,我不认为这是这种情况,因为来自QThread的sendToTable()
方法最多只被调用5-6次,并且threadCount
永远不会大于20大多数,但我通常把它保持在5左右。
答案 0 :(得分:2)
而且,像往常一样,我在调试2天后回答我的问题,在SO上发布后几分钟。
在所有线程启动后,我有一个剩余的workerThread.wait()
方法调用。很自然地,我的应用程序完成了它所要做的事情 - 等待线程完成。
我删除了那个方法调用,并将QCoreApplication.processEvents()
放在启动线程的循环中,现在它就像魅力一样。
再一次,谢谢你,SO的无形,全能的人!