zoukankan      html  css  js  c++  java
  • pyQt5 任务处理进度条

    这里我们用一个更新程序做示例, 下载文件的过程中让进度条实时显示下载进度。

    如果下载和更新进度条的工作都放在一个线程中,会出现进度条卡顿的情况。

    正确的做法是把界面刷新和工作任务交给不同的线程去运行,然后用信号同步。

    # _*_  coding: utf-8  _*_
    import os
    import sys
    import subprocess
    from PyQt5.QtCore import (QThread, pyqtSignal, QRect)
    from PyQt5.QtWidgets import (QApplication, QDesktopWidget, QProgressBar, QWidget, QLabel, QFrame, QPushButton)
    from PyQt5.QtGui import (QIcon, QPixmap)
    import requests
    import zipfile
    import json
    
    class dfThread(QThread):
        _signal = pyqtSignal(int, str, str)
    
        def __init__(self, download_url, filesize, fileobj, buffer):
            super().__init__()
            self.download_url = download_url
            self.filesize = filesize
            self.fileobj = fileobj
            self.buffer = buffer
    
        def run(self):
            try:
                f = requests.get(self.download_url, stream=True)
                offset = 0
                for chunk in f.iter_content(chunk_size=self.buffer):
                    if not chunk:
                        break
                    self.fileobj.seek(offset)
                    self.fileobj.write(chunk)
                    offset = offset + len(chunk)
                    proess = offset / int(self.filesize) * 100
                    self._signal.emit(int(proess), str(offset), str(self.filesize))
                self.fileobj.close()
                self.exit(0)
            except Exception as e:
                print(e)
    
    class zipFile(object):
        def __init__(self, filename, mode='r', basedir=''):
            self.filename = filename
            self.mode = mode
            if self.mode in ('w', 'a'):
                self.zfile = zipfile.ZipFile(filename, self.mode, compression=zipfile.ZIP_DEFLATED)
            else:
                self.zfile = zipfile.ZipFile(filename, self.mode)
            self.basedir = basedir
            if not self.basedir:
                self.basedir = os.path.dirname(filename)
    
        def close(self):
            self.zfile.close()
    
        def extract_to(self, path):
            for p in self.zfile.namelist():
                self.extract(p, path)
    
        def extract(self, filename, path):
            if not filename.endswith('/'):
                f = os.path.join(path, filename)
                dir = os.path.dirname(f)
                if not os.path.exists(dir):
                    os.makedirs(dir)
                try:
                    open(f, 'wb').write(self.zfile.read(filename))
                except IOError:
                    pass
    
    class updateFrm(QWidget):
        def __init__(self):
            super().__init__()
            self.mainfn  = 'QQ'
            #self.fileuri = 'http://a.b.cn/serv/update/%s.zip' % self.mainfn
            self.fileuri = 'https://dldir1.qq.com/qqfile/qq/PCQQ9.1.1/24953/QQ9.1.1.24953.exe'
            #self.servurl = 'http://a.b.cn/serv/version'
            self.baseTitle = 'QQ升级助手'
            self.initUI()
    
        def initUI(self):
            self.info = QLabel(self)
            self.info.move(65, 28)
            self.info.resize(360, 40)
    
            map = QLabel(self)
            map.move(30, 25)
            img = QPixmap('res\info.png')
            map.setPixmap(img)
    
            self.tips = QLabel(self)
            self.tips.move(420, 55)
            self.tips.resize(30, 10)
            self.tips.hide()
    
            self.line = QFrame(self)
            self.line.setGeometry(QRect(0, 75, 500, 75))
            self.line.setFrameShape(QFrame.HLine)
            self.line.setFrameShadow(QFrame.Sunken)
            self.line.setObjectName("line")
    
            self.btnQuit = QPushButton(self)
            self.btnQuit.setText("取消")
            self.btnQuit.setGeometry(380, 120, 100, 30)
            self.btnQuit.clicked.connect(self.cancel)
            self.btnQuit.hide()
    
            self.btnStart = QPushButton(self)
            self.btnStart.setText('立即更新')
            self.btnStart.setGeometry(380, 120, 100, 30)
            self.btnStart.clicked.connect(self.start)
    
    
            self.bar = QProgressBar(self)
            self.bar.setGeometry(0, 110, 530, 2)
            self.bar.setMaximum(100)
            self.bar.hide()
    
            self.setFixedSize(500, 160)
            self.center()
            self.setWindowTitle(self.baseTitle)
            icon = QIcon()
            icon.addPixmap(QPixmap("res\6.ico"), QIcon.Normal, QIcon.Off)
            self.setWindowIcon(icon)
    
            try:
                #res = requests.get(self.servurl)
                #obj = json.loads(res.text)
                obj = {
                    'title': '发现新版本',
                    'desc' : 'PCQQ 9.1.1 全新改版,给你焕然一新的感觉'
                }
                txt = '%s
    
    %s' % (obj['title'], obj['desc'])
            except Exception as e:
                txt = '未发现新版本
    
    '
                self.btnStart.setDisabled(True)
            self.info.setText(txt)
    
            self.show()
    
        def center(self):
            qr = self.frameGeometry()
            cp = QDesktopWidget().availableGeometry().center()
            qr.moveCenter(cp)
            self.move(qr.topLeft())
    
        def cancel(self):
            self.close()
    
        def start(self):
            self.btnStart.hide()
            self.bar.show()
            self.tips.show()
            self.line.hide()
            self.btnQuit.setEnabled(False)
            self.btnQuit.show()
            self.downloadfile()
    
        def downloadfile(self):
            self.bar.setValue(0)
            path = '%s.zip' % self.mainfn
            self.filesize = requests.get(self.fileuri, stream=True).headers['Content-Length']
            self.fileobj  = open(path, 'wb')
            self.dfThread = dfThread(self.fileuri, self.filesize, self.fileobj, buffer=10240)
            self.dfThread._signal.connect(self.progressinfo)
            self.dfThread.start()
    
        def progressinfo(self, per, f_size_dl, f_size):
            self.bar.setValue(per)
            self.tips.setText('%s%%' % str(per))
            self.info.setText('升级过程中请勿退出
    
    正在下载.. %s/%s bytes' % (str(f_size_dl), str(f_size)))
            if per == 100:
                self.info.setText('升级过程中请勿退出
    
    下载完成,正在安装..')
                self.unzip('%s.zip' % self.mainfn)
                self.tips.hide()
                self.info.setText('安装完成
    
    已升级到最新版本')
                self.btnQuit.setText('完成')
                self.btnQuit.setEnabled(True)
    
        def unzip(self, fname):
            z = zipFile(fname)
            z.extract_to('.')
            z.close()
            os.remove(fname)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        frm = updateFrm()
        #kill = subprocess.call(("taskkill /F /IM %s.exe" % frm.mainfn), shell=True)
        sys.exit(app.exec_())
  • 相关阅读:
    使用数据库时注意单引号、双引号和反引号的区别
    Mysql中的事件
    C#使用WindowsMediaPlayer实现视频播放
    Chart控件,鼠标选择区域,可以局部放大缩小
    C#自定义控件在添加引用后不显示在工具箱的解决方法(转)
    C# 中的#if、#elif、#else、#endif等条件编译符号
    若有派生类,则基类中的析构函数要用虚函数
    迭代器失效
    this指针
    VS调试快捷键
  • 原文地址:https://www.cnblogs.com/6min/p/10775977.html
Copyright © 2011-2022 走看看