“如何使用 yt-dlp api 提供的下载百分比更新 PyGtk 中的进度条?”

问题描述 投票:0回答:0

我一直在用 python 编写一个小项目来练习 gui,但是我在处理 gtk 进度条的这一部分有点卡住了。 我认为问题与 yt-dlp 在开始下载时阻塞主线程有关,或者因为 gtk 不允许另一个线程修改它自己的元素。 这是我的代码:

窗口.py

from downloader.download import Downloader
from time import sleep
import gi
import threading
# from multiprocessing import Process
from db.database import Data
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib


class ProgressUpdate(threading.Thread):
    def __init__(self, progress_bar, downloader):
        super().__init__()
        self.progress_bar = progress_bar
        self.downloader = downloader
        self.is_running = True

    def stop(self):
        self.is_running = False

    def run(self):
        while self.is_running:
            percent = self.downloader.percent
            print('Percent', percent)
            if percent and percent != 0:
                GLib.idle_add(self._update_progres_bar, percent)
            sleep(0.5)

    def _update_progress_bar(self, percent):
        self.progress_bar.set_fraction(percent)
        return False

class Window(Gtk.Window):
    
    def __init__(self):
        super().__init__(title="Downloader")
        self.notebook = Gtk.Notebook()
        self.add(self.notebook)

        # Init conection with database
        self.data = Data()
        self.data.create_connection()

        # Display page of window
        self.display_download()
        self.display_history()

        self.link = ''

         ...
    # more code
         ...

    # callback function called when 'download' button is pressed

    def __on_button_clicked(self, widget):
        # Process for download
        link = self.download_entry.get_text()

        if link != "":
            self.progress_bar.set_fraction(0)
            downloader = Downloader()
            updater = ProgressUpdate(self.progress_bar, downloader)

            updater.start()
            downloader.download(link) # Using yt-dlp
            updater.stop()

            self.progress_bar.set_fraction(1)

下载器.py

import yt_dlp as dl
# import os


LINK = ''


class Downloader:
    def __init__(self):
        self.status = ''
        self.percent = None


    # Clean percent value
    def __clean_percent(self, percent):
        for i, char in enumerate(percent):
            if char == '%':
                value = percent[i-5:i+1].replace('%', '')
                break
        try:
            value = (float(value.replace(' ', '')) / 100)
        except Exception as e:
            print(e)

        return value

    def my_hook(self, d):
        if d['status'] == 'downloading':
            self.percent = self.__clean_percent(d['_percent_str'])
        elif d['status'] == 'finished':
            self.status = 'finished'

    def download(self, link=LINK):
        opts = {
            'progress_hooks': [self.my_hook],
        }
        with dl.YoutubeDL(opts) as ytdl:
            ytdl.download([link])


if __name__ == '__main__':
    d = Downloader()
    d.download()

我只想用下载百分比更新进度条。

python gtk pygtk youtube-dl
© www.soinside.com 2019 - 2024. All rights reserved.