如何在这段代码上应用 PyQt QThread
How To Apply PyQt QThread on this Piece of code
# -*- 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 以动态更新进度条的帮助,而无需 "Not Responding problem"
我阅读了很多主题,我可以理解 Qthread 的主要概念,但仍然无法理解如何将它应用到我的代码中,考虑到下载功能与下载按钮相关联而不是 运行无限。
我应该创建一个子 Qthread class 或者我能做什么?
如果你能帮我举例说明如何将它与上面的代码一起使用,我会将它应用到我的 Gui 应用程序的其余代码中..
提前致谢。
当实现 QThread 时,要执行的任务应该在 运行() 方法中完成,如果你想用线程提供的数据更新 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 代码。
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")
# -*- 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 以动态更新进度条的帮助,而无需 "Not Responding problem"
我阅读了很多主题,我可以理解 Qthread 的主要概念,但仍然无法理解如何将它应用到我的代码中,考虑到下载功能与下载按钮相关联而不是 运行无限。
我应该创建一个子 Qthread class 或者我能做什么?
如果你能帮我举例说明如何将它与上面的代码一起使用,我会将它应用到我的 Gui 应用程序的其余代码中..
提前致谢。
当实现 QThread 时,要执行的任务应该在 运行() 方法中完成,如果你想用线程提供的数据更新 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 代码。
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")