PyQt5笔记——基于QThread的zip文件解压线程

364 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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('解压异常')