如何在这段代码上应用PyQt-QThread

2024-03-19 08:50:04 发布

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

# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.uic import loadUiType
import youtube_dl
import pafy
import urllib.request
import urllib.parse
from urllib.parse import *
import win32clipboard
import sys
import os
import humanize
import subprocess
import time
import shutil
import re
from pySmartDL import SmartDL
from os.path import splitext, basename
from os import path


Close = False
ShutDown = False
Sleep = False
Restart = False
Paused = False
Stopped = False
Start = True
Resume = True

if getattr(sys, 'frozen', False):
    # frozen
    dir_ = os.path.dirname(sys.executable)
else:
    # unfrozen
    dir_ = os.path.dirname(os.path.realpath(__file__))
FORM_CLASS, _ = loadUiType(path.join(dir_, "main.ui"))


class MainApp(QMainWindow, FORM_CLASS):

    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        QMainWindow.__init__(self)
        self.setupUi(self)
        self.lineEdit.installEventFilter(self)
        self.lineEdit_3.installEventFilter(self)
        self.lineEdit_6.installEventFilter(self)
        self.Handle_Ui()
        self.Handle_Buttons()



    def closeEvent(self, evnt):
        if self._want_to_close:
            super(MainApp, self).closeEvent(evnt)
            sys.exit()

    def Handle_Ui(self):
        #self.lineEdit.setFocus()
        self.setFixedSize(861,441)


    def Handle_Buttons(self):
        self.pushButton_3.clicked.connect(self.open_file_loction)
        self.pushButton_2.clicked.connect(self.Start)
        self.pushButton_13.clicked.connect(self.Pause)
        self.pushButton_14.clicked.connect(self.Stop)
        self.pushButton.clicked.connect(self.Handle_Browse)
        self.pushButton_4.clicked.connect(self.Download_youtube_video)
        self.pushButton_10.clicked.connect(self.get_quality)
        self.pushButton_5.clicked.connect(self.Browse2)
        self.pushButton_6.clicked.connect(self.open_file_location2)
        self.pushButton_11.clicked.connect(self.Search_Qualities)
        self.pushButton_7.clicked.connect(self.Browse3)
        self.pushButton_9.clicked.connect(self.download_playlist)
        self.pushButton_8.clicked.connect(self.open_file_location3)
        self.pushButton_12.clicked.connect(self.open_video)
        self.comboBox_2.currentIndexChanged.connect(self.Action_Happened)
        self.comboBox_3.currentIndexChanged.connect(self.Action_Happened)
        self.comboBox_4.currentIndexChanged.connect(self.Action_Happened)

    def Start(self):
        global Start
        global Stopped
        global Paused
        Start = True
        Stopped = False
        Paused = False
        self.Download()

    def Pause(self):
        global Paused
        global Start
        global Resume
        if self.pushButton_13.text()=="Pause Downloading":
            Paused = True
            Start = False
            Stopped = False
            Resume = False
            self.pushButton_13.setText("Resume Downloading")
            QApplication.processEvents()
        elif self.pushButton_13.text()=="Resume Downloading":
            Start = True
            Paused = False
            Resume = True
            Stopped = False
            self.pushButton_13.setText("Pause Downloading")
            QApplication.processEvents()



    def Stop(self):
        global Stopped
        global Start
        Stopped = True
        Start = False
        Paused = False
        self.Download()


    def Download(self):
        directory = os.path.expanduser("~") + "\AppData\Local\Temp\pySmartDL"
        if not os.path.exists(directory):
            os.makedirs(directory)
        try:
            global Paused
            global Stopped
            global Start
            global XX
            url = self.lineEdit.text()
            save_location = self.lineEdit_2.text()
            obj = SmartDL(url, progress_bar=False)
            if Start == True:
                try:
                    obj.start(blocking=False)
                    while True:
                        self.progressBar.setValue(obj.get_progress()*100)
                        self.label_8.setText("Downloaded: " + str(obj.get_dl_size(human=True)))
                        self.label_38.setText("Speed: " + str(obj.get_speed(human=True)))
                        self.label_39.setText("Remaining Time: " + str(obj.get_eta(human=True)))
                        time.sleep(0.2)
                        QApplication.processEvents()
                        if Paused == True:
                            obj.pause()
                            QApplication.processEvents()
                        if Resume == True:
                                obj.unpause()
                                QApplication.processEvents()
                        if obj.isFinished():
                            break
                        if Stopped == True:
                            obj.stop()
                            self.progressBar.setValue(0)
                            break

                    if obj.isSuccessful():
                        #os.rename(obj.get_dest(), save_location)
                        shutil.move(obj.get_dest(), save_location)

                    if Close == True:
                        QApplication.quit()
                    elif ShutDown == True:
                        os.system('shutdown -s')
                    elif Sleep == True:
                        os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")
                    elif Restart == True:
                        subprocess.call(["shutdown", "/r"])
                    if Stopped == False:
                        QMessageBox.information(self, "Download Completed", "Your Download is Completed")
                except:
                    QMessageBox.warning(self, "Download Error", "Download Failed")
                    pass
        except Exception as e:
            pass



def main():
    app = QApplication(sys.argv)
    window = MainApp()
    window.show()
    app.exec_()

if __name__ == '__main__':
    main()

我一直在寻找关于如何在上面的代码中应用Qthread来动态更新进度条而不出现“无响应问题”的帮助

我读过很多主题,我可以理解Qthread的主要概念,但是考虑到下载函数与一个不无限运行的下载按钮相连,我仍然无法理解如何将它应用到我的代码中。在

我应该创建一个sub-Qthread类还是应该做什么?在

如果你能帮我举一个例子来说明如何将它与上面的代码一起使用,我将把它应用到我的Gui应用程序的剩余代码上。。在

提前谢谢。在


Tags: importselffalsetrueobjifosdef
1条回答
网友
1楼 · 发布于 2024-03-19 08:50:04

当实现一个QThread时,要执行的任务应该在run()方法中完成,如果您想用线程提供的数据更新GUI,那么不应该直接通过信号来完成,因为GUI应该只在这个GUI线程调用的主线程中更新。在

class DownloadThread(QThread):
    dataChanged = pyqtSignal(int, str, str, str)
    Started, Paused, Resume, Stopped = range(4)
    downloadError = pyqtSignal()
    downloadFinished = pyqtSignal()

    def __init__(self, parent=None):
        QThread.__init__(self, parent)
        self.state = DownloadThread.Stopped
        self.params = {"url": "", "save_location": ""}

    def setParams(self, params):
        self.params = params

    def setState(self, state):
        self.state = state

    def run(self):
        obj = SmartDL(self.params["url"], progress_bar=False)
        try:
            obj.start(blocking=False)
            while True:
                self.dataChanged.emit(obj.get_progress() * 100,
                                      str(obj.get_dl_size(human=True)),
                                      str(obj.get_speed(human=True)),
                                      str(obj.get_eta(human=True)))
                time.sleep(0.2)
                if self.state == DownloadThread.Paused:
                    obj.pause()
                if self.state == DownloadThread.Resume:
                    obj.unpause()
                    self.state = DownloadThread.Started
                if obj.isFinished():
                    break
                if self.state == DownloadThread.Stopped:
                    obj.stop()
                    self.progressBar.setValue(0)
                    break
            if obj.isSuccessful():
                # os.rename(obj.get_dest(), save_location)
                shutil.move(obj.get_dest(), self.params["save_location"])
                if self.state == DownloadThread.Started:
                    self.downloadFinished.emit()
        except:
            self.downloadError.emit()

您应该避免使用全局变量,此外,您可以减少几个变量,这些变量一次只更新一个变量,所以我不得不修改GUI代码。在

^{pr2}$

相关问题 更多 >