You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Pytube与PySide6 Progress Bar结合实现下载进度显示?

PySide6 YouTube下载进度条实现方案

核心逻辑

把下载任务放到独立线程中执行,避免阻塞GUI主线程;通过PySide6的Signal将下载进度从子线程传递到主线程,主线程接收信号后更新进度条。

代码改造示例

1. 定义下载线程类

这个类负责执行下载任务,并通过信号发送进度:

from PySide6.QtCore import QThread, Signal
import yt_dlp

class DownloadThread(QThread):
    # 定义进度更新信号,参数为进度百分比(0-100)
    progress_updated = Signal(int)
    # 定义下载完成信号,参数表示是否成功
    download_finished = Signal(bool)

    def __init__(self, url, save_path, quality, parent=None):
        super().__init__(parent)
        self.url = url
        self.save_path = save_path
        self.quality = quality

    def run(self):
        # 进度回调函数,由yt-dlp触发
        def progress_callback(data):
            if data['status'] == 'downloading':
                # 计算当前下载进度
                downloaded = data.get('downloaded_bytes', 0)
                total = data.get('total_bytes', data.get('total_bytes_estimate', 1))
                progress = int((downloaded / total) * 100)
                self.progress_updated.emit(progress)
            elif data['status'] == 'finished':
                self.download_finished.emit(True)

        # yt-dlp配置项
        ydl_config = {
            'format': self.quality,
            'outtmpl': f'{self.save_path}/%(title)s.%(ext)s',
            'progress_hooks': [progress_callback],
        }

        try:
            with yt_dlp.YoutubeDL(ydl_config) as ydl:
                ydl.download([self.url])
        except Exception as e:
            print(f"下载错误: {str(e)}")
            self.download_finished.emit(False)

2. 主窗口中集成线程与进度条

在你的MainWindow类中,绑定线程信号到进度条,并处理下载触发逻辑:

from PySide6.QtWidgets import QMainWindow
from ui_mainwindow import Ui_MainWindow

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # 绑定下载按钮点击事件(根据你的UI控件名称调整)
        self.download_btn.clicked.connect(self.start_download)
        self.download_thread = None

    def start_download(self):
        # 获取用户输入的参数
        video_url = self.url_input.text().strip()
        save_dir = self.save_path_input.text().strip()
        selected_quality = self.quality_combo.currentText()

        if not video_url or not save_dir:
            return

        # 初始化并启动下载线程
        self.download_thread = DownloadThread(video_url, save_dir, selected_quality)
        # 连接进度信号到进度条的setValue方法
        self.download_thread.progress_updated.connect(self.progressBar.setValue)
        # 连接完成信号处理后续操作
        self.download_thread.download_finished.connect(self.handle_download_result)
        # 启动线程
        self.download_thread.start()

    def handle_download_result(self, success):
        # 下载完成后的处理逻辑
        self.progressBar.setValue(0)
        if success:
            print("下载完成")
            # 可添加弹窗提示、日志记录等操作
        else:
            print("下载失败")

关键注意事项

  • 禁止子线程操作UI:所有对进度条等UI控件的更新必须通过信号在主线程执行,PySide6不允许跨线程直接操作UI。
  • 进度计算容错:yt-dlp的回调数据中,total_bytes可能为空,需用total_bytes_estimate作为备选。
  • 线程资源管理:下载完成后可通过finished信号清理线程对象,避免内存泄漏。

内容的提问来源于stack exchange,提问作者WigoWigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 22:05:04