Your code has a major issue: the while thread_request_token.is_alive(): pass line creates a blocking loop that freezes the GUI until the thread finishes. This is not ideal, as it prevents Tkinter from updating the interface properly. Instead, you should use a callback function once the thread completes.
Here’s a better version of your code using threading and Tkinter's after() method, which allows the UI to remain responsive:
import threading
def change_login_to_wait():
frame_waiting.grid(row=0, column=0, padx=10, pady=10)
frame_discord_login.grid_forget()
def change_wait_to_session():
frame_discord_session.grid(row=0, column=0, padx=10, pady=10)
frame_autoticket.grid(row=0, column=1, padx=10, pady=10)
frame_waiting.grid_forget()
def request_token():
"""Function that runs in a separate thread to request token."""
bls_at.request_discord_token(input_email.get(), input_password.get())
def on_login_complete():
"""Called once the login process completes."""
lbl_discord_username.configure(text=bls_at.USER_NAME)
change_wait_to_session()
def login_user():
change_login_to_wait()
# Start thread for request, then check its completion using after()
thread_request_token = threading.Thread(target=request_token)
thread_request_token.start()
# Schedule a periodic check without freezing the GUI
check_thread_completion(thread_request_token)
def check_thread_completion(thread):
"""Checks if the thread is alive, then schedules another check."""
if thread.is_alive():
frame_waiting.after(100, lambda: check_thread_completion(thread))
else:
on_login_complete()
btn_login = CTkButton(
frame_discord login,
text="Login",
command=login user,
width=LOGIN_ELEMENTS_WIDTH
)