Reputation: 31
I'm trying to learn Tkinter/CustomTkinter, so I followed a guide that made a YouTube video downloader with CustomTkinter GUI
But when I download a video, the program freezes for like 10 mins then it actually downloads.
import tkinter
import customtkinter
from pytube import YouTube
def startdownload():
try:
ytLink = link.get()
ytObject = YouTube(ytLink, on_progress_callback=on_progress)
video = ytObject.streams.get_lowest_resolution()
title.configure(text=ytObject.title)
video.download()
finishlabel.configure(text="Downloaded")
except:
finishlabel.configure(text="Invlaid")
def on_progress(stream, chunk, bytes_remaning):
total_size = stream.filesize
bytes_downloaded = total_size - bytes_remaning
percentage_of_compeletion = bytes_downloaded / total_size * 100
per = str(int(percentage_of_compeletion))
number.configure(text=per + "%")
number.update()
bar.set(float(percentage_of_compeletion) / 100)
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("blue")
app = customtkinter.CTk()
app.geometry("720x480")
app.title("Youtube Downloader")
title = customtkinter.CTkLabel(app, text="Enter Video Link")
title.pack(padx=10, pady=10)
url_var = tkinter.StringVar()
link = customtkinter.CTkEntry(app, width=350, height=40, textvariable=url_var)
link.pack()
finishlabel = customtkinter.CTkLabel(app, text="")
finishlabel.pack()
number = customtkinter.CTkLabel(app, text="0%")
number.pack()
bar = customtkinter.CTkProgressBar(app, width=400)
bar.set(0)
bar.pack(padx=10, pady=10)
download = customtkinter.CTkButton(app, width=200, text="Download", command=startdownload)
download.pack(padx=10, pady=10)
#app run loop
app.mainloop()
Tried askingChatGPT, but that didn't help0
Upvotes: 3
Views: 164
Reputation: 310
When you press the download button, the program needs to download a YouTube video. itis a time consuming task, if run on the main thread, will make the application freeze until the download completes. This happens because the main thread is responsible for updating the GUI, and if it's busy with downloading, it can't update the interface.
You used threading to run the download task on a separate thread, allowing the main thread to remain free to update the GUI and keep the application responsive.
import tkinter
import customtkinter
from pytube import YouTube
import threading
def download_video():
try:
ytLink = link.get()
ytObject = YouTube(ytLink, on_progress_callback=on_progress)
video = ytObject.streams.get_lowest_resolution()
title.configure(text=ytObject.title)
video.download()
finishlabel.configure(text="Downloaded")
except:
finishlabel.configure(text="Invlaid")
def startdownload():
down_thread = threading.Thread(target=download_video)
down_thread.daemon = True
down_thread.start()
def on_progress(stream, chunk, bytes_remaning):
total_size = stream.filesize
bytes_downloaded = total_size - bytes_remaning
percentage_of_compeletion = bytes_downloaded / total_size * 100
per = str(int(percentage_of_compeletion))
number.configure(text=per + "%")
number.update()
bar.set(float(percentage_of_compeletion) / 100)
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("blue")
app = customtkinter.CTk()
app.geometry("720x480")
app.title("Youtube Downloader")
title = customtkinter.CTkLabel(app, text="Enter Video Link")
title.pack(padx=10, pady=10)
url_var = tkinter.StringVar()
link = customtkinter.CTkEntry(app, width=350, height=40, textvariable=url_var)
link.pack()
finishlabel = customtkinter.CTkLabel(app, text="")
finishlabel.pack()
number = customtkinter.CTkLabel(app, text="0%")
number.pack()
bar = customtkinter.CTkProgressBar(app, width=400)
bar.set(0)
bar.pack(padx=10, pady=10)
download = customtkinter.CTkButton(app, width=200, text="Download", command=startdownload)
download.pack(padx=10, pady=10)
#app run loop
app.mainloop()
will help : https://www.geeksforgeeks.org/how-to-use-thread-in-tkinter-python/
Upvotes: 0