我正在用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.
可能下次花更多时间研究? –
谢谢,你非常有帮助。我花了2天时间对此进行调试。 –