本篇主要是梳理一下,在使用 Pyside2 模块的时候,利用多线程处理页面假死【exe未响应】的问题
一、 这边举个例子吧【如下图所示】
-
测试代码如下
class Stats(): def __init__(self): # 从文件中加载UI定义 super().__init__() qfile_stats = QFile(f'{os.getcwd()}\\thread.ui') qfile_stats.open(QFile.ReadOnly) qfile_stats.close() self.ui = QUiLoader().load(f'{os.getcwd()}\\thread.ui') # 重置倒退进度条的进度 self.ui.progressBar.reset() self.ui.progressBar.setValue(0) # 按钮绑定执行方法 self.ui.pushButton.clicked.connect(self.test_1) '''点击触发进度条增加''' def test_1(self): for i in range(1,101): self.ui.progressBar.setValue(i) time.sleep(1)
二、问题出现的原因
界面中,通常会有一些按钮,点击后触发事件
如去下载一个文件或做一些操作,这些操作会耗时
如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态
三、问题解决办法 【多线程】
优化后的代码:
res_lock = Lock()
class Stats(QObject):
# 实例化一个信号槽函数
progress_sigal = Signal(int)
textBrowser_results_sigal = Signal(str)
def __init__(self):
# 从文件中加载UI定义
super().__init__()
qfile_stats = QFile(f'{os.getcwd()}\\thread.ui')
qfile_stats.open(QFile.ReadOnly)
qfile_stats.close()
self.ui = QUiLoader().load(f'{os.getcwd()}\\thread.ui')
# 重置倒退进度条的进度
self.ui.progressBar.reset()
self.ui.progressBar.setValue(0)
self.ui.pushButton.clicked.connect(self.test_1)
# 使用到了 lambda 函数,信号槽函数连接方法
self.progress_sigal.connect(lambda x: self.ui.progressBar.setValue(x))
self.textBrowser_results_sigal.connect(lambda y: self.ui.textBrowser.append(y))
'''点击触发进度条增加'''
def test_1(self):
for i in range(0,101,5):
# 操作共享数据前,申请获取锁
res_lock.acquire()
self.ui.progressBar.setValue(i)
# 发射信号,通知 UI 更新
self.textBrowser_results_sigal.emit(f"当前进度:{i}%")
time.sleep(0.1)
# 发射信号,通知 UI 更新
self.progress_sigal.emit(i)
# 操作共享数据后,释放锁
res_lock.release()