到目前为止,我基本上是这样的:
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保持响应,它就可以花很长时间。因此,基本上是一个“后台”线程。