python中的多文件下载和进度条更新

2024-04-25 09:34:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试构建一个GUI日志文件下载工具

我正在尝试使用pyqt5线程工作程序同时下载多个文件

我正在使用回调(paramiko支持)函数来确定下载百分比。我想同时更新特定下载的进度条。我不知道如何将progressBar详细信息传递给回调函数。 我想通过“progressBar”来测试函数(它是一个回调函数)

from PyQt5 import QtCore, QtGui, QtWidgets
import threading
import time
from concurrent.futures import ThreadPoolExecutor
from configurationFileRead import readConfigFile
import paramiko
import os
from functools import partial


class FileDownload1(QtCore.QThread):
    percentage = QtCore.pyqtSignal(str, str)
    def __init__(self, fileList, serverList, listProgressBar):
        super().__init__()
        self.fileList = fileList
        self.serverList = serverList
        self.listProgressBar = listProgressBar
    def test(self, size, fileSize):
        sPercentage=((fileSize - size)/fileSize)*100
        if sPercentage != 100:
            sPercentage = 100 - sPercentage
        print(sPercentage)
        
    def _download(self, fileName, serverName, progressBar):
        userId = readConfigFile().getUserId(serverName)
        password = readConfigFile().getPassword(serverName)
        ipAddress = readConfigFile().getIpAddress(serverName)
        logPath = readConfigFile().getLogPath(serverName)
        ssh = paramiko.SSHClient()
        ssh.load_system_host_keys()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ipAddress, username=userId, password=password)
        ftp_client=ssh.open_sftp()
        print(str(os.getcwd()))
        try:
            ftp_client.get(logPath+"/"+fileName,str(os.getcwd())+"/"+fileName, callback = lambda s, t : self.percetage.emit(s, t))
        except Excption as e:
            print(e)
        ftp_client.close()
        ssh.close()
    def run(self):
        j = 0
        with ThreadPoolExecutor(max_workers = 1) as executor:
            while(j < len(self.fileList)):
                if(self.fileList[j].isChecked()):
                    
                    future= executor.submit(self._download, self.fileList[j].text(), self.serverList[j].text(), self.listProgressBar[j])
                j = j+1
        print("Download END")


class logSearch(QtCore.QThread):
    new_signal = QtCore.pyqtSignal(dict)
    def __init__(self, serverList, serachString, archiveFlg, component):
        super().__init__()
        self.serverList = serverList
        self.searchString = serachString
        self.archiveFlg = archiveFlg
        self.component = component
        self.result = {}
    def fileSearch(self, server, searchText):
        try:

            userId = readConfigFile().getUserId(server.text())
            password = readConfigFile().getPassword(server.text())
            ipAddress = readConfigFile().getIpAddress(server.text())
            logPath = ""

            if(not self.archiveFlg):
                logPath = readConfigFile().getLogPath(server.text())
            else:
                logPath = readConfigFile().getLogArchivePath(server.text())
            ssh = paramiko.SSHClient()
            ssh.load_system_host_keys()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(ipAddress, username=userId, password=password)
            if(not self.archiveFlg):
                if self.component == "":
                    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("cd "+logPath+";for i in *.log\ndo grep -li '"+self.searchString+"' $i\ndone")
                else:
                    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("cd "+logPath+";for i in "+self.component+"_*.log\ndo grep -li '"+self.searchString+"' \"$i\"\ndone")
                    
            else:
                print(logPath)
                ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("cd "+logPath+";grep -lri '"+self.searchString+"' .")
            temp1 = ssh_stderr.read()
            print(temp1)
            temp = ssh_stdout.read().decode('utf-8')
            print(temp)
            temp =temp.strip()
            files = list(temp.split("\n"))
            files = list(filter(None,files))
            i = len(files)
            j=0
            tempDict = {}
            while(j < i):
                ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("cd "+logPath+";ls -l "+files[j])
                temp = ssh_stdout.read().decode('utf-8')
                tempLi = list(temp.split(" "))
                tempLi = list(filter(None,tempLi))
                fileSize = tempLi[4]
                tempFileSize  =  int(fileSize)
                if(tempFileSize < 1024):

                    fileSize = str(round(tempFileSize,2)) + " B"
                else:
                    tempFileSize = tempFileSize/1024
                    if(tempFileSize < 1024):
                        fileSize = str(round(tempFileSize,2)) + " KB"
                    else:
                        tempFileSize = tempFileSize/1024
                        if(tempFileSize < 1024):
                            fileSize = str(round(tempFileSize,2))+ " MB"
                        else:
                            tempFileSize = tempFileSize/1024
                            fileSize = str(round(tempFileSize,2)) + " GB"


                fileDate = str(tempLi[5])+" "+str(tempLi[6])+" "+str(tempLi[7])
                tempLi.clear()
                tempDict[files[j]] = {'Size':fileSize,'Date':fileDate}
                j = j+1
            self.result[server.text()]= tempDict
            ssh.close()

        except Exception as e:
            print(e)
    def run(self):
        i=len(self.serverList)
        mxW=0
        if(i == 1):
            mxW = 1
        elif(i == 2 or i == 3 or i == 4):
            mxW = 2
        elif(i == 5 or i == 6):
            mxW = 3
        else:
            mxW = 5
        with ThreadPoolExecutor(max_workers = mxW) as executor:
            j=0
            try:
                while(j < i):
                    future = executor.submit(self.fileSearch, self.serverList[j], self.searchString)
                    j = j+1
            except Exception as e:
                print(e)
        self.new_signal.emit(self.result)

class Ui_MainWindow(object):
    def _Validate (self):
        validateFlag = True
        if(str(self.searchString.text())== ""):
            self.searchString.setStyleSheet("border: 2px solid red;")
            self.searchString.setFocus()
            validateFlag = False
        else:
            self.searchString.setStyleSheet("border: 1px solid;")
        if(len(self.serverList.selectedItems())) == 0:
            self.serverList.setStyleSheet("border: 2px solid red;")
            validateFlag = False
        elif len(self.serverList.selectedItems()) > 8:
            self.selectedServer.setText("You can only Choose Upto 8 Server")
            self.selectedServer.setStyleSheet("color:blue;font:Bold")
            self.serverList.setStyleSheet("border: 2px solid red;")
            validateFlag = False
        elif len(self.serverList.selectedItems()) > 1 and self.specificFileFlag.isChecked() == True:
            self.selectedServer.setText("Select only one Server")
            self.selectedServer.setStyleSheet("color:red;font:Bold")
            validateFlag = False
        else:
            self.serverList.setStyleSheet("border: 1px solid;")
        if(validateFlag):
            self.downloadSelected.setDisabled(True)
            i=len(self.listProgressBar)
            n=0
            while(i > 0):
                self.listProgressBar[n].deleteLater()
                self.listCheckBox[n].deleteLater()
                self.listDateLabel[n].deleteLater()
                self.listSizeLabel[n].deleteLater()
                self.listServerLabel[n].deleteLater()
                i = i-1;
                n=n+1
            self.listProgressBar.clear()
            self.listCheckBox.clear()
            self.listDateLabel.clear()
            self.listSizeLabel.clear()
            self.listServerLabel.clear()
            self.submit.setDisabled(True)
            self.errorLabel.setText("Search Started...")
            self.logSearch = logSearch(self.serverList.selectedItems(), self.searchString.text(), self.searchArchive.isChecked(), self.comonentComboBox.currentText())
            self.logSearch.new_signal.connect(self.printResult)
            self.logSearch.start()
    def printResult(self, result):
        self.errorLabel.setText("Search Completed")
        serverList = list(result.keys())
        print(result)
        l = len(serverList)
        k=0
        m = 0
        i = 0
        while(i < l):
            logNameList = list(result[serverList[i]].keys())
            n= len(logNameList)
            j=0
            while(j < n):
                self.listCheckBox.append(QtWidgets.QCheckBox())
                self.listSizeLabel.append(QtWidgets.QLabel(result[serverList[i]][logNameList[j]]['Size']))
                self.listDateLabel.append(QtWidgets.QLabel(result[serverList[i]][logNameList[j]]['Date']))
                self.listCheckBox[m].setText(logNameList[j])
                self.gridLayout_2.addWidget(self.listCheckBox[m], m, 0)
                self.listServerLabel.append(QtWidgets.QLabel())
                self.listServerLabel[m].setText(serverList[i])
                self.gridLayout_2.addWidget(self.listServerLabel[m], m, 1)
                self.gridLayout_2.addWidget(self.listSizeLabel[m], m, 2)
                self.gridLayout_2.addWidget(self.listDateLabel[m], m, 3)
                self.listProgressBar.append(QtWidgets.QProgressBar())
                self.listProgressBar[m].setValue(0)
                self.gridLayout_2.addWidget(self.listProgressBar[m], m, 4)
                j = j+1
                m=m+1
            i = i+1
        self.submit.setDisabled(False)
        self.downloadSelected.setDisabled(False)
    def hello122(self):
        print("invoked")
    def _FileDownload(self):
        self.test = FileDownload1(self.listCheckBox, self.listServerLabel, self.listProgressBar)
        self.test.percentage.connect(self.hello122)
        self.test.start()
    def _ArchiveFlag(self):
        if (self.searchArchive.isChecked()):
            self.autoDownload.setChecked(True)
            self.autoDownload.setDisabled(True)
        else:
            self.autoDownload.setDisabled(False)
    def _FileDownloadFlag(self):
        if(self.specificFileFlag.isChecked()):
            self.label.setText("<html><head/><body><p><span style=\" font-weight:600; color:#000000;\">File Name</span><span style=\" font-weight:600; color:#ff0000;\">*</span></p></body></html>")
            self.submit.setText("Download File")
            self.autoDownload.setChecked(False)
            self.autoDownload.setDisabled(True)
            self.searchArchive.setDisabled(True)
            self.comonentComboBox.hide()
            self.downloadSelected.setDisabled(True)
        else:
             self.label.setText("<html><head/><body><p><span style=\" font-weight:600; color:#000000;\">Search String</span><span style=\" font-weight:600; color:#ff0000;\">*</span></p></body></html>")
             self.submit.setText("Search")
             self.comonentComboBox.show()
             self.autoDownload.setDisabled(False)
             self.searchArchive.setDisabled(False)
    def _serverList(self):
            if len(self.serverList.selectedItems()) > 8 :
                self.selectedServer.setText("You can only Choose Upto 8 Server")
                self.selectedServer.setStyleSheet("color:red;font:Bold")
            elif len(self.serverList.selectedItems()) > 1 and self.specificFileFlag.isChecked() == True:
                self.selectedServer.setText("Select only one Server")
                self.selectedServer.setStyleSheet("color:red;font:Bold")
            elif len(self.serverList.selectedItems()) == 0:
                self.selectedServer.setText("")
            else:
                self.selectedServer.setText(str([item.text() for item in self.serverList.selectedItems()]))
                self.selectedServer.setStyleSheet("color:black;font:regular")
                self.serverList.setStyleSheet("border: 1px solid;")


    def setupUi(self,MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(823, 588)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 40, 761, 60))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        self.gridLayout.setObjectName("gridLayout")
        self.label = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1, QtCore.Qt.AlignLeft)
        self.searchString = QtWidgets.QLineEdit(self.verticalLayoutWidget)
        self.searchString.setMaximumSize(QtCore.QSize(673, 16777215))
        self.searchString.setObjectName("searchString")
        self.gridLayout.addWidget(self.searchString, 0, 1, 1, 1)
        self.submit = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.submit.setObjectName("submit")
        self.gridLayout.addWidget(self.submit, 0, 4, 1, 1)
        self.componentLabel = QtWidgets.QLabel(self.verticalLayoutWidget)
        self.componentLabel.setObjectName("componentLabel")
        self.gridLayout.addWidget(self.componentLabel, 0, 2, 1, 1)
        self.comonentComboBox = QtWidgets.QComboBox(self.verticalLayoutWidget)
        self.comonentComboBox.setObjectName("comonentComboBox")
        self.comonentComboBox.addItem("")
        lengthOfComponent = len(readConfigFile().getComponentList())
        m=0
        while(m < lengthOfComponent):
            self.comonentComboBox.addItem(readConfigFile().getComponentList()[m])
            m = m+1
        self.gridLayout.addWidget(self.comonentComboBox, 0, 3, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout)
        self.errorLabel = QtWidgets.QLabel(self.centralwidget)
        self.errorLabel.setGeometry(QtCore.QRect(30, 10, 751, 16))
        self.errorLabel.setText("")
        self.errorLabel.setObjectName("errorLabel")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(40, 140, 361, 151))
        self.groupBox.setObjectName("groupBox")
        self.serverList = QtWidgets.QListWidget(self.groupBox)
        self.serverList.setEnabled(True)
        self.serverList.setGeometry(QtCore.QRect(10, 20, 331, 121))
        self.serverList.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
        self.serverList.setResizeMode(QtWidgets.QListView.Fixed)
        self.serverList.setObjectName("serverList")
        item = QtWidgets.QListWidgetItem()
        lengthOfServers = len(readConfigFile().getServerList())
        k=0
        while( k < lengthOfServers):
            if readConfigFile().getServerList()[k] != "Component":
                self.serverList.addItem(readConfigFile().getServerList()[k])
            k = k+1
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setGeometry(QtCore.QRect(410, 140, 361, 151))
        self.groupBox_2.setObjectName("groupBox_2")
        self.autoDownload = QtWidgets.QCheckBox(self.groupBox_2)
        self.autoDownload.setGeometry(QtCore.QRect(10, 30, 121, 20))
        self.autoDownload.setObjectName("autoDownload")
        self.specificFileFlag = QtWidgets.QCheckBox(self.groupBox_2)
        self.specificFileFlag.setGeometry(QtCore.QRect(10, 60, 171, 20))
        self.specificFileFlag.setObjectName("specificFileFlag")
        self.downloadSelected = QtWidgets.QPushButton(self.groupBox_2)
        self.downloadSelected.setGeometry(QtCore.QRect(10, 97, 141, 31))
        self.downloadSelected.setObjectName("downloadSelected")
        self.searchArchive = QtWidgets.QCheckBox(self.groupBox_2)
        self.searchArchive.setGeometry(QtCore.QRect(170, 30, 141, 20))
        self.searchArchive.setObjectName("searchArchive")
        self.checkBox = QtWidgets.QCheckBox(self.groupBox_2)
        self.checkBox.setGeometry(QtCore.QRect(170, 60, 191, 21))
        self.checkBox.setObjectName("checkBox")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(640, 540, 161, 20))
        self.label_2.setObjectName("label_2")
        self.selectedServer = QtWidgets.QLabel(self.centralwidget)
        self.selectedServer.setGeometry(QtCore.QRect(30, 110, 751, 21))
        self.selectedServer.setText("")
        self.selectedServer.setObjectName("selectedServer")
        self.serverList.itemSelectionChanged.connect(self._serverList)
        self.submit.clicked.connect(self._Validate)
        self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(40, 310, 731, 211))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.scrollArea = QtWidgets.QScrollArea(self.horizontalLayoutWidget)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 727, 207))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
        self.gridLayout_2.setContentsMargins(10, 10, 10, 10)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.horizontalLayout.addWidget(self.scrollArea)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.listCheckBox = []
        self.listProgressBar = []
        self.listServerLabel = []
        self.listSizeLabel = []
        self.listDateLabel = []
        self.searchArchive.toggled.connect(self._ArchiveFlag)
        self.specificFileFlag.toggled.connect(self._FileDownloadFlag)
        self.downloadSelected.clicked.connect(self._FileDownload)
        self.downloadSelected.setDisabled(True)
        self.checkBox.setDisabled(True)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-weight:600; color:#000000;\">Search String</span><span style=\" font-weight:600; color:#ff0000;\">*</span></p></body></html>"))
        self.submit.setText(_translate("MainWindow", "Search"))
        self.groupBox.setTitle(_translate("MainWindow", "Server List"))
        __sortingEnabled = self.serverList.isSortingEnabled()
        self.serverList.setSortingEnabled(False)
        self.serverList.setSortingEnabled(__sortingEnabled)
        self.groupBox_2.setTitle(_translate("MainWindow", "Other Configuration"))
        self.autoDownload.setToolTip(_translate("MainWindow", "<html><head/><body><p><br/></p></body></html>"))
        self.autoDownload.setText(_translate("MainWindow", "Auto Download"))
        self.specificFileFlag.setToolTip(_translate("MainWindow", "<html><head/><body><p>write the file name in &quot;Search String&quot; and Click on Search Button</p></body></html>"))
        self.specificFileFlag.setText(_translate("MainWindow", "Download Specific file"))
        self.downloadSelected.setText(_translate("MainWindow", "Download Selected"))
        self.searchArchive.setText(_translate("MainWindow", "Search in Archive"))
        self.checkBox.setToolTip(_translate("MainWindow", "<html><head/><body><p>This option will try to compress the file in server before downloading</p></body></html>"))
        self.checkBox.setText(_translate("MainWindow", "Compress Before Download"))
        self.label_2.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" color:#969696;\">Created by - Sudipto Khan</span></p></body></html>"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())


Tags: selfifdefsshtranslatesettextserverlistqtcore
1条回答
网友
1楼 · 发布于 2024-04-25 09:34:11

您无法访问主Qt线程之外的GUI元素,因此必须将地址列表发送到Qt线程,并使用自定义信号通知进程,然后在主线程中可以使用地址作为每个地址栏的引用

我假设您可能正在使用QTableWidget,因此下面的示例使用第一列作为服务器名,第二列作为文件名,第三列显示QProgressBar(使用^{}添加)

FileDownload1(QtCore.QThread):
    percentage = QtCore.pyqtSignal(str, str, int)
    def __init__(self, urlData):
        super().__init__()
        self.urlData = urlData

    def _download(self, fileName, serverName):
        # ...
        try:
            ftp_client.get(
                logPath+"/"+fileName, 
                str(os.getcwd())+"/"+fileName, 
                callback = lambda s, t: self.percentage.emit(server, path, int(s / t * 100)))
        # ...

    def run(self):
        j = 0
        with ThreadPoolExecutor(max_workers = 1) as executor:
            for serverName, fileName in self.urlData:
                future = executor.submit(self._download, serverName, fileName)

class MainWindow(QtWidgets.QMainWindow):
    # ...
    def startDownload(self):
        urlData = []
        self.progressBars = {}
        for row in range(self.fileTable.rowCount()):
            serverName = self.fileTable.item(row, 0).text()
            fileName = self.fileTable.item(row, 1).text()
            urlData.append((serverName, fileName))
            progressBar = self.fileTable.cellWidget(row, 2)
            self.progressBars[(serverName, fileName)] = progressBar
        self.downloader = FileDownload1(urlData)
        self.downloader.percentage.connect(self.percentageUpdate)
        self.downloader.start()

    def percentageUpdate(self, serverName, fileName, percentage):
        self.progressBars[(serverName, fileName)].setValue(percentage)

相关问题 更多 >