Little Frezno
Little Frezno

Reputation: 31

Program freezing in Python CustomTkinter

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

Answers (1)

Thisal
Thisal

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

Related Questions