PyQt5实现下载进度条

起因是因为公司要开发一款自动登录某网站的助手工具提供给客户使用,要使用到selenium,所以选择了pyqt5的方式来开发这个C/S架构的客户端

在过程中要用到自动更新的功能,所以自己写一个下载进度的插件给大家分享,本人编程水平有点菜,不要见怪。

界面文件UI_download.py

# -*- coding: utf-8 -*-

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import Qt

class Ui_download(object):
    def setupUi(self, Dialog):
        Dialog.setWindowFlags(Qt.FramelessWindowHint)
        Dialog.setObjectName("Dialog")
        Dialog.resize(300, 56)
        Dialog.setFixedSize(Dialog.width(), Dialog.height())
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
        Dialog.setSizePolicy(sizePolicy)
        Dialog.setSizeGripEnabled(True)
        self.gridLayout = QtWidgets.QGridLayout(Dialog)
        self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        self.gridLayout.setObjectName("gridLayout")
        self.progressBar = QtWidgets.QProgressBar(Dialog)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
        self.progressBar.setObjectName("progressBar")
        self.gridLayout.addWidget(self.progressBar, 1, 0, 1, 1)
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.label.setText(_translate("Dialog", "客户端更新下载中..."))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_download()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

实现文件download.py

# -*- coding: utf-8 -*-

"""
Module implementing Dialog.
"""

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QDialog
from PyQt5 import QtWidgets
from Ui_download import Ui_download
import os
import sys
import requests


class downloadThread(QThread):

    download_proess_signal = pyqtSignal(int)

    def __init__(self, download_url, filesize, fileobj, buffer):
        super(downloadThread, self).__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.download_proess_signal.emit(int(proess))
            self.fileobj.close()
            self.exit(0)
        except Exception as e:
            print(e)


class download(QDialog, Ui_download):
    """
    下载类实现
    """
    def __init__(self, download_url, auto_close=True, parent=None):
        """
        Constructor
        
        @download_url:下载地址
        @auto_close:下载完成后时候是否需要自动关闭
        """
        super(download, self).__init__(parent)
        self.setupUi(self)
        self.progressBar.setValue(0)
        self.downloadThread = None
        self.download_url = download_url
        self.filesize = None
        self.fileobj = None
        self.auto_close = auto_close
        self.download()

    def download(self):
        self.filesize = requests.get(self.download_url, stream=True).headers['Content-Length']
        path = os.path.join("update", os.path.basename(self.download_url))
        self.fileobj = open(path, 'wb')
        self.downloadThread = downloadThread(self.download_url, self.filesize, self.fileobj, buffer=10240)
        self.downloadThread.download_proess_signal.connect(self.change_progressbar_value)
        self.downloadThread.start()

    def change_progressbar_value(self, value):
        self.progressBar.setValue(value)
        if self.auto_close and value == 100:
            self.close()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ui = download()
    ui.show()
    sys.exit(app.exec_())

比较通用的一个下载模块,初始化调用的时候只需要传入要下载的地址就行,下载操作采取异步,以防阻塞UI,确保程序目录下拥有update目录存在,默认我是将要更新的文件放在这个目录下面,还有优化的地方希望大家可以指出。

运行后效果:


猜你喜欢

转载自blog.csdn.net/rain_of_mind/article/details/79989715