持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情
前言
- 对于PyQt的GUI程序来说,当遇到计算密集型的操作时,需要单独创建一个线程处理密集计算的操作,否则,在进行计算操作时,UI界面会出现假死现象,带来不佳的用户体验。
- 对于PyQt开发,创建一个线程的方法是:创建一个以QThread为基类的类,然后在run()方法中编写相应的计算操作。之后就可以实例化一个线程对象,调用start()方法启动线程。
- 解压操作是一个挺耗费CPU和时间的操作,随着压缩文件的增大,计算量也增大。因此也需要单独创建一个线程进行处理,否则用户会以为到GUI程序卡死了。
本文要点
- 解压文件方法基于第三方库:zipfile(安装命令:
pip install zipfile) - 本文基于QThread封装了一个zip文件解压的线程类(UnzipQThread类继承QThread)
- 技术实现:QTread多线程+pyqtSignal信号+zipfile解压
代码实现
- 代码如下:
import zipfile
import os
from tqdm import tqdm
from PyQt5.QtCore import QThread, pyqtSignal
class UnzipQThread(QThread):
'''
解压线程
'''
signal_unzip_process = pyqtSignal(list) # 解压进度信号
signal_unzip_finished = pyqtSignal(bool) # 解压完成信号(参数表示是否异常)
def __init__(self, zip_src, dst_dir):
super().__init__()
self.zip_src = zip_src
self.dst_dir = dst_dir
def unzip_file(self, zip_src, dst_dir):
'''
解压缩
'''
r = zipfile.is_zipfile(zip_src)
if r:
fz = zipfile.ZipFile(zip_src, 'r') # 创建解压文件对象
total_file = len(fz.namelist())
unzip_num = 0
for file in fz.namelist(): # 遍历压缩包文件列表
fz.extract(file, dst_dir) # 解压file文件到dst_dir目录下
unzip_num += 1
self.signal_unzip_process.emit([unzip_num, total_file]) # 发送自定义信号,与主进程交互,显示进度/更新进度条
self.signal_unzip_finished.emit(True)
else:
print('This is not zip')
self.signal_unzip_finished.emit(False)
def run(self):
self.unzip_file(self.zip_src, self.dst_dir)
在PyQt程序中使用(实现与主进程的交互):
unzip_thread = UnzipQThread(zip_src='压缩文件路径', dst_dir='解压路径')
unzip_thread.signal_unzip_process.connect(update_process)
unzip_thread.signal_unzip_finished .connect(unzip_finished)
unzip_thread.start() # 启动线程
def update_process(val):
print('解压进度:',val[0],'/',val[1])
def unzip_finished(state):
if state:
print('解压完成')
else:
print('解压异常')