如何在这段代码上应用 PyQt QThread [英] How To Apply PyQt QThread on this Piece of code

查看:49
本文介绍了如何在这段代码上应用 PyQt QThread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

# -*- 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 以动态更新进度条而没有无响应问题"的帮助

I've been looking around for help on how to Apply Qthread on the above piece of code to update the progress Bar Dynamically with no "Not Responding problem"

我已经阅读了很多主题,我可以理解 Qthread 的主要概念,但仍然无法理解如何将其应用到我的代码中,因为下载功能与下载按钮相连,而不是无限运行.

I've read many topics and I could understand the main concept of Qthread but still can't get the idea on how to Apply it to my Code taking in consideration that download function is connected with a download button not running infinitely.

我应该创建一个子 Qthread 类还是我可以做什么?

should I make a sub Qthread class or what can I do ?

如果你能帮我举个例子说明如何在上面的代码中使用它,我会将它应用到我的 Gui 应用程序的其余代码中..

If You Can help me with an example on how to use it with the above piece of code and I will Apply it on the remaining code of my Gui App..

提前致谢.

推荐答案

当实现一个 QThread 时,要执行的任务应该在 run() 方法中完成,如果你想用线程提供的数据更新 GUI 应该不能直接完成,而是通过信号完成,因为 GUI 应该只在由此 GUI 线程调用的主线程中更新.

When implementing a QThread the task to be performed should be done in the run () method, if you want to update the GUI with data provided by the thread should not be done directly but through signals since the GUI should only be updated in the main thread called by this the GUI thread.

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 代码.

You should avoid using global variables in addition that you can reduce several variables that are all updated at once by only one variable so I had to modify the GUI code.

class MainApp(QMainWindow, FORM_CLASS):
    def __init__(self, parent=None):
        # ...
        self.Handle_Buttons()
        self.download = DownloadThread(self)
        self.download.dataChanged.connect(self.onDataChanged)
        self.download.downloadError.connect(self.errorDownload)
        self.download.downloadFinished.connect(self.successfulDownload)

    def closeEvent(self, evnt):
        # ...

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

    def Handle_Buttons(self):
        # ...

    def onDataChanged(self, progress, downloaded, speed, remain):
        self.progressBar.setValue(progress)
        self.label_8.setText("Downloaded: " + downloaded)
        self.label_38.setText("Speed: " + speed)
        self.label_39.setText("Remaining Time: " + remain)

    def Start(self):
        directory = os.path.expanduser("~") + "\AppData\Local\Temp\pySmartDL"
        if not os.path.exists(directory):
            os.makedirs(directory)
        params = {"url": self.lineEdit.text(),
                  "save_location": self.lineEdit_2.text()}
        self.download.setParams(params)
        self.download.setState(DownloadThread.Started)
        self.download.start()

    def Pause(self):
        if self.pushButton_13.text() == "Pause Downloading":
            self.download.setState(DownloadThread.Paused)
            self.pushButton_13.setText("Resume Downloading")
        elif self.pushButton_13.text() == "Resume Downloading":
            self.download.setState(DownloadThread.Resume)
            self.pushButton_13.setText("Pause Downloading")

    def Stop(self):
        self.download.setState(DownloadThread.Stopped)
        self.progressBar.setValue(0)

    def errorDownload(self):
        QMessageBox.warning(self, "Download Error", "Download Failed")

    def successfulDownload(self):
        QMessageBox.information(self, "Download Completed", "Your Download is Completed")

这篇关于如何在这段代码上应用 PyQt QThread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆