我正在编写从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()`
答案 0 :(得分:1)
The issue which appears to be is that you need to call self.DownloadFile
and self.show_progress_ba
r 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()