python - PyQt5,QThread:如何在线程中运行非循环函数时保持 GUI 响应?
问题描述
我到目前为止基本上是这样的:
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 同时保持响应,它就可以根据需要进行。所以,基本上是一个“背景”线程。
解决方案
推荐阅读
- java - 如何从arraylist中制作一个哈希图,其中一列具有重复值的键是键,对应的行是值
- html - 引导轮播图像未显示
- php - Cakephp 2.x 在没有模型的控制器中设置自定义验证消息
- azure - 用于监控的遥测与组织洞察
- c# - 如何做自动大小的分组框?
- gutenberg-blocks - Gutenberg is not saving my custom block data
- php - 使用控制台安装 SDK
- python - AWS region in AWS Glue
- oracle - ORACLE SQL ORA-00918: 查询时列定义不明确
- rxjs - 在 Angular6 服务中使用 EventEmitter