Python:tkinter进度栏未更新

问题描述

以下代码中的进度栏​​永远不会更新,对于方法show_progress,从if语句开始的代码也永远不会运行。 每当下载开始时,我需要更新进度条和标签downloading_progress_value,并在下载完成时停止进度条。谁能告诉我错误在哪里?

注意:为简单起见,我删除了一些控件。 Python版本:3.7和 Pytube版本:9.6.4

import threading
from tkinter import *
from tkinter import messageBox as mBox
from tkinter import ttk

from pytube import YouTube


class Application:
    def __init__(self,root):
        self.root = root
        self.video_url = "https://www.youtube.com/watch?v=fjHW5kBvonY"

        ########################### This label used to show the progress when download starts  ###########################
        self.downloading_progress_value = StringVar()
        self.downloading_progress = Label(self.root,text=" ",textvariable=self.downloading_progress_value)
        self.downloading_progress.place(x=114,y=190)

        self.progress_bar = ttk.Progressbar(self.root,orient=HORIZONTAL,length=425,mode="determinate")
        self.progress_bar.place(x=114,y=215)

    ########################### starting the dowload  ###########################
    def start_download(self):
        self.app_download = DownloadApp(self.progress_bar,self.video_url.get(),self.folder_name,self.choices_var.get(),self.downloading_progress_value)

    ########################### the class responsible for downloading operations  ###########################
class DownloadApp:
    def __init__(self,progress_bar,youtube_url,media_folder,media_choice,downloading_progress_value):
        self.progress_bar = progress_bar
        self.youtube_url = youtube_url
        self.media_folder = media_folder
        self.media_choice = media_choice
        self.downloading_progress_value = downloading_progress_value

        self.youtube = YouTube(url=youtube_url)
        if self.media_choice == "1":
            self.youtube_stream = self.youtube.streams.filter(progressive=True,file_extension="mp4").order_by('resolution').desc().first()
            self.youtube_stream.download(output_path=self.media_folder,filename=self.youtube_stream.title)
            self.max_file_size = self.youtube_stream.filesize

        if self.media_choice == "2":
            self.youtube_stream = self.youtube.streams.filter(only_audio=True,file_extension="webm").first()
            self.youtube_stream.download(output_path=self.media_folder,filename=self.youtube_stream.title)
            self.max_file_size = self.youtube_stream.filesize

        self.downloading_progress_value.set("Downloading is in progress....")
        threading.Thread(target=self.youtube.register_on_progress_callback(self.show_progress)).start()
        threading.Thread(target=self.download_file).start()

    def show_progress(self,stream=None,chunk=None,file_handle=None,bytes_remaining=None):
        self.percent_count = float("%.2f" (100 - ( 100 * (bytes_remaining /self.max_file_size))))
        mBox.showinfo("Test 1","test the method 1")
        print(self.percent_count)
        if self.percent_count < 100:
            self.downloading_progress_value.set(str(self.percent_count))
            self.progress_bar['value'] = self.percent_count
        else:
            self.progress_bar.stop()
            self.downloading_progress_value.grid_forget()
            self.progress_bar.grid_forget()
        mBox.showinfo("Test 2","test the method 2")

    def download_file(self):
        if self.media_choice == "1":
            self.youtube_stream = self.youtube.streams.filter(progressive=True,file_extension="mp4").order_by('resolution').desc().first().download(output_path=self.media_folder,filename=self.youtube_stream.title)
        if self.media_choice == "2":
            self.youtube_stream = self.youtube.streams.filter(only_audio=True,file_extension="webm").first().download(output_path=self.media_folder,filename=self.youtube_stream.title)
        mBox.showinfo("Download Finished","Video downloaded successfully")


if __name__ == "__main__":
    window = Tk()
    window.title("Youtube Downloader")
    window.geometry("1020x550+400+210")
    window.resizable(0,0)

    app = Application(window)
    mainloop()

解决方法

show_progress()中进行字符串转换时出错。

percent_count = float("%.2f" % (100 - ( 100 * (bytes_remaining/max_file_size))))
# missing -------------------^

您收到此错误吗?还是行得通?如果是这样,您从转化中获得了什么价值?

,
def show_progress(self,stream=None,chunk=None,file_handle=None,bytes_remaining=None):

show_progress()函数应仅接受3个参数-streamchunkbytes_remaining,按此顺序。这样做的方式是,pytube将bytes_remaining参数传递给file_handle参数。

此外,我认为您应该在计算percent_count的表达式前放置一个'%'字符,像这样-

self.percent_count = float("%.2f" %(100 - ( 100 * (bytes_remaining /self.max_file_size))))

请告知是否可以解决问题。

编辑:我还要指出的另一件事是,即使在注册on_progress_callback或调用download_file()方法之前,DownloadApp类的 init 方法实际上仍会下载文件。这不仅意味着您的进度回调不会在第一次下载时被调用,而且还可以确保也不会在第二次调用时(因为pytube在文件已经存在的情况下会跳过下载)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...