线程退出后Qt处理信号?

时间:2012-11-29 04:42:49

标签: python multithreading qt pyqt pyside

我正在使用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左右。

1 个答案:

答案 0 :(得分:2)

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

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

我删除了那个方法调用,并将QCoreApplication.processEvents()放在启动线程的循环中,现在它就像魅力一样。

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

相关问题