如何结合pytube和tkinter标签来显示进度?

时间:2018-03-25 15:02:19

标签: python-3.x tkinter pytube

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

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

Code 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()` 

1 个答案:

答案 0 :(得分:1)

The issue which appears to be is that you need to call self.DownloadFile and self.show_progress_bar at the same time as you mentioned. To call both functions at the same time the best solution is to use thread library

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()