【问题标题】:How to combine pytube and tkinter label to show progress?如何结合 pytube 和 tkinter 标签来显示进度?
【发布时间】:2018-03-25 15:02:18
【问题描述】:

我正在编写从 youtube 下载歌曲的小程序(使用 pytube) 我想添加 python tkinter GUI 以在文件下载时显示百分比值。

现在当我执行我的代码时,程序首先下载文件(大约需要 60 秒),然后才显示 100% 的标签。如果我想在下载文件的同时看到标签值从 0% 上升到 100%,我应该在代码中进行哪些更改?

代码 Python3:

from pytube import YouTube
import tkinter as tk
from tkinter import ttk

# main application shows:
# label Loading..
# label which configure values when file is downloading 
# inderterminate progress bar
class MainApplication(tk.Frame):

def __init__(self, master=None, *args, **kwargs):
    tk.Frame.__init__(self, master)
    self.master = master

    self.master.grid_rowconfigure(0, weight=0)
    self.master.grid_columnconfigure(0, weight=1)

    self.youtubeEntry = "https://www.youtube.com/watch?v=vVy9Lgpg1m8"
    self.FolderLoacation = "C:/Users/Jonis/Desktop/"

    # pytube
    self.yt = YouTube(self.youtubeEntry)

    video_type = self.yt.streams.filter(only_audio = True).first()

    # file size of a file
    self.MaxfileSize = video_type.filesize

    # Loading label
    self.loadingLabel = ttk.Label(self.master, text="Loading...", font=("Agency FB", 30))
    self.loadingLabel.grid(pady=(100,0))

    # loading precent label which must show % donwloaded
    self.loadingPercent = tk.Label(self.master, text="", fg="green", font=("Agency FB", 30))
    self.loadingPercent.grid(pady=(30,30))

    # indeterminate progress bar
    self.progressbar = ttk.Progressbar(self.master, orient="horizontal", length=500, mode='indeterminate')
    self.progressbar.grid(pady=(50,0))
    self.progressbar.start()    

    # call Download file func
    self.DownloadFile


def DownloadFile(self):
    self.yt.register_on_progress_callback(self.show_progress_bar)
    self.yt.streams.filter(only_audio=True).first().download(self.FolderLoacation)

# func count precent of a file
def show_progress_bar(self, stream=None, chunk=None, file_handle=None, bytes_remaining=None):

    # loadingPercent label configure value %
    self.loadingPercent.config(text=str(100 - (100*(bytes_remaining/self.MaxfileSize))))


root = tk.Tk()
root.title("Youtube downloader")
root.geometry("1920x1080")
app = MainApplication(root)
root.mainloop()` 

【问题讨论】:

    标签: python-3.x tkinter pytube


    【解决方案1】:

    问题似乎是您需要同时致电self.DownloadFileself.show_progress_bar,就像您提到的那样。同时调用这两个函数最好的解决方案是使用线程库

    from pytube import YouTube
    import tkinter as tk
    from tkinter import ttk
    import threading
    
    
    # main application shows:
    # label Loading..
    # label which configure values when file is downloading 
    # inderterminate progress bar
    class MainApplication(tk.Frame):
    
    def __init__(self, master=None, *args, **kwargs):
        tk.Frame.__init__(self, master)
        self.master = master
    
        self.master.grid_rowconfigure(0, weight=0)
        self.master.grid_columnconfigure(0, weight=1)
    
        self.youtubeEntry = "https://www.youtube.com/watch?v=vVy9Lgpg1m8"
        self.FolderLoacation = "C:/Users/Jonis/Desktop/"
    
        # pytube
        self.yt = YouTube(self.youtubeEntry)
    
        video_type = self.yt.streams.filter(only_audio = True).first()
    
        # file size of a file
        self.MaxfileSize = video_type.filesize
    
        # Loading label
        self.loadingLabel = ttk.Label(self.master, text="Loading...", font=("Agency FB", 30))
        self.loadingLabel.grid(pady=(100,0))
    
        # loading precent label which must show % donwloaded
        self.loadingPercent = tk.Label(self.master, text="0", fg="green", font=("Agency FB", 30))
        self.loadingPercent.grid(pady=(30,30))
    
        # indeterminate progress bar
        self.progressbar = ttk.Progressbar(self.master, orient="horizontal", length=500, mode='indeterminate')
        self.progressbar.grid(pady=(50,0))
        self.progressbar.start()    
    
        threading.Thread(target=self.yt.register_on_progress_callback(self.show_progress_bar)).start()
    
        # call Download file func
        threading.Thread(target=self.DownloadFile).start()
    
    
    
    def DownloadFile(self):
    
    
        self.yt.streams.filter(only_audio=True).first().download(self.FolderLoacation)
    
    # func count precent of a file
    def show_progress_bar(self, stream=None, chunk=None, file_handle=None, bytes_remaining=None):
    
        # loadingPercent label configure value %
        self.loadingPercent.config(text=str(int(100 - (100*(bytes_remaining/self.MaxfileSize)))))
    
    
    root = tk.Tk() 
    root.title("Youtube downloader")
    root.geometry("1920x1080")
    app = MainApplication(root)
    root.mainloop()
    

    【讨论】:

    • 计数并不总是从 100 开始
    • 输出错误:percent = (100 * (fileSizeInBytes - remaining)) / fileSizeInBytes TypeError: unsupported operand type(s) for -: 'int' and 'NoneType'
    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多