PyQt5,QThread:如何在线程中运行非循环功能时保持GUI响应?

时间:2018-09-06 08:36:53

标签: python multithreading pyqt5 qthread

到目前为止,我基本上是这样的:

from PyQt5 import QtCore
import time

class WorkerThread(QtCore.QThread):
    def __init__(self, app, ml, parent=None):
        self.p = app
        self.ml = ml
        QtCore.QThread.__init__(self, parent)

    def run(self):
        self.ml()

class HelperClassForGUI:
    def __init__(self, app):
        self.p = app

    def mainFunc(self):
        self.thread = WorkerThread(self.p, SomeHeavyFunction)
        self.thread.finished.connect(self.done)
        self.thread.start()

    def done(self):
        ...

所以我有一个来自外部库的函数(“ SomeHeavyFunction”)(因此我无法控制它),如果正常调用,它需要几秒钟才能完成,因此冻结了GUI,所以我想使用同时保持GUI响应的线程。

问题是,该应用程序仍然冻结。 'done()'函数应按预期执行,因此我可以假定带有该函数的线程实际上已正确终止,但是没有显示出所需的效果。

为了进行测试,我尝试了一个类似这样的函数,而不是实际的“ SomeHeavyFunction”:

def func(self):
    self.idx = 0
    while self.idx < 100:
        if (self.idx % 3 == 0):
            self.p.statusBar.showMessage('Calculating ..')
        elif (self.idx % 3 == 1):
            self.p.statusBar.showMessage('Calculating. .')
        elif (self.idx % 3 == 2):
            self.p.statusBar.showMessage('Calculating.. ')
        self.idx += 1
        time.sleep(1)

有了这个,GUI保持响应,但是在这里我有一个不同的问题,如果我在线程期间尝试与GUI进行过多交互(例如,试图显示更大的工具提示),或者我经常出现GUI崩溃的情况。将等待时间从1秒减少到0.1秒。

所以,我的问题是:我想念什么?我需要怎么做才能使GUI保持响应并且不会崩溃?如上所述,我无法访问SomeHeavyFunction,我只能调用它,而不能将其拆分为可循环的片段或类似的东西(我从大多数教程中看到的是,它们将调用“ processEvents”以保持GUI响应并且它们的线程通常是某种简单的循环,我无法真正将其应用于我的问题)。

编辑:重点放在“不是循环的功能”上。我无法控制SomeHeavyFunction()。它不包含一个循环,并且我没有任何方法可以从中发送任何周期性信号。我需要的是SomeHeavyFunction()在某个(异步?)线程中启动,只要在此期间GUI保持响应,它就可以花很长时间。因此,基本上是一个“后台”线程。

0 个答案:

没有答案