PyQt5开发YouTube下载器时进度条无法显示下载百分比问题求助
问题根因
- 类方法缩进错误:
savePathWork、downloadWork两个槽函数缩进不符合Python规范,不属于YoutubeMain类的成员,按钮点击无法触发对应逻辑 - 进度回调注册顺序错误:先执行了
stream[0].download()下载逻辑,才去注册进度回调,下载过程完全不会触发回调函数 - 重复实例化YouTube对象且参数错误:已经实例化了
video = pytube.YouTube(url),后续又重复创建yt=YouTube(url.text()),但url本身是字符串没有text()属性,会直接抛出异常 - 进度记录变量作用域错误:
previousprogress是回调函数的局部默认参数,每次调用都会重置为0,无法正确记录上一次进度 - 主线程阻塞:下载逻辑直接在UI主线程执行,阻塞UI事件循环,就算有进度回调也无法实时更新进度条UI
修复步骤
- 修正两个槽函数的缩进,将其归入
YoutubeMain类内部 - 删去重复创建的YouTube对象,直接在第一次创建的
video对象上注册进度回调,且注册操作要放在download执行之前 - 将
previousprogress改为类实例属性,避免每次回调被重置 - 下载前重置进度条值为0,避免上次下载进度影响当前显示
修正后完整代码
from PyQt5.QtWidgets import * from PyQt5.QtCore import * import pytube import re import os import subprocess from pytube.__main__ import YouTube from Youtube import Ui_MainWindow class YoutubeMain(QMainWindow): def __init__(self): super().__init__() QMainWindow.__init__(self) self.ui=Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle('Youtube Downloader') self.ui.comboBox.addItem('mp3') self.ui.comboBox.addItem('avi') self.ui.comboBox.addItem('mov') self.ui.comboBox.addItem('wmv') # 初始化进度记录变量 self.previousprogress = 0 self.show() self.initSignal() def initSignal(self) : self.ui.pushButton.clicked.connect(self.downloadWork) self.ui.toolButton.clicked.connect(self.savePathWork) def progress_bar(self,chunk, stream, file_handle, bytes_remaining): total_size = stream.filesize bytes_download = total_size - bytes_remaining liveprogress = int(bytes_download / total_size * 100) if liveprogress > self.previousprogress: self.previousprogress = liveprogress self.ui.progressBar.setValue(liveprogress) print(liveprogress) @pyqtSlot() def savePathWork(self) : fpath = QFileDialog.getExistingDirectory(self, 'Select the Directory') self.ui.save_textEdit.setText(fpath) @pyqtSlot() def downloadWork(self) : url = self.ui.dl_textEdit.text().strip() save = self.ui.save_textEdit.text() regex = re.compile('^https://www.youtube.com/watch?') if not url: self.ui.dl_textEdit.setFocus(True) return None if not save: return None if regex.match(url) is not None : # 重置进度 self.previousprogress = 0 self.ui.progressBar.setValue(0) # 创建YouTube对象后立即注册进度回调 video = pytube.YouTube(url) video.register_on_progress_callback(self.progress_bar) stream = video.streams.all() down_dir = self.ui.save_textEdit.text() # 注册完成后再执行下载 stream[0].download(down_dir) if self.ui.checkBox.isChecked() : oriFiileName = stream[0].default_filename newFileName = os.path.splitext(oriFiileName)[0] subprocess.call(['ffmpeg','-i', os.path.join(down_dir, oriFiileName), os.path.join(down_dir, newFileName + '.' + str(self.ui.comboBox.currentText())) ]) if __name__=="__main__": import sys app=QApplication(sys.argv) root= YoutubeMain() sys.exit(app.exec_())
进阶优化建议:可将下载和转码逻辑移到QThread子线程中执行,避免UI卡顿,转码进度也可通过自定义信号同步到UI显示。
内容的提问来源于stack exchange,提问作者mobinhb
相关产品推荐
相关产品推荐

