2

我正在构建一个带有 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信号连接到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 中的主表。

但是,当我一次运行多个线程时会出现问题。Worker 线程完成他们的工作,但有时只会发出 Signal。或者,更好的是,它就像 Qt(或其他)正在等待所有线程完成,然后更新表一样发出。这就是实际发生的情况——我可以在 Python 控制台中看到线程正在执行它们的任务,一旦它们在做它们正在做的任何事情,表格就会突然立即填充一堆数据。

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

我已经尝试将其添加Qt.DirectConnection到该connect()方法中,但这并没有真正帮助。

额外问题:我一直在 SO 和其他网站上阅读有关此主题的内容,似乎人们推荐QRunnable()而不是QThread()特别推荐子类化它。因此,我会使用QThreadPool(). 但是当我尝试这个时,似乎我无法从 a 发出信号QRunnable- 它给了我AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect',即使 Signal 是在 QRunnable 类中定义的 - 这很奇怪,我必须说。

编辑:在关于 SO 的另一个答案中,有人提到可能正在向主 GUI 线程“发送垃圾邮件”,其中包含要处理的事件。但是,我不相信这是这种情况,因为sendToTable()来自 QThread 的方法最多只从线程调用 5-6 次,并且最多threadCount不大于 20,但我通常将其保持在 5 左右.

4

1 回答 1

2

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

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

我删除了该方法调用,并将QCoreApplication.processEvents()启动线程的循环放入其中,现在一切都像魅力一样工作。

再次感谢SO的隐形全能者!

于 2012-11-29T05:06:26.730 回答