I’m building a GUI to update a report, and currently I’m getting an error with tkinter library.
I tried add a function to check if the window still exists, but the error remains.
Here is the code:
import customtkinter
import datetime
import os
import shutil
import tkinter
System Settings
customtkinter.set_appearance_mode(“System”)
customtkinter.set_default_color_theme(“blue”)
Creates GUI frame with 720 width by 480 height
app = customtkinter.CTk()
app.geometry(“720×480”)
Function to center window on the screen
def center_window(window, width, height):
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x = (screen_width // 2) - (width // 2)
y = (screen_height // 2) - (height // 2)
window.geometry(f"{width}x{height}+{x}+{y}")
Center the main application window
center_window(app, 720, 480)
Sets the title of the main application window
app.title(“Finance Report”)
Creates a label for the date input box
title = customtkinter.CTkLabel(app, text=”Insert date (yyyymmdd)”)
title.pack(padx=10, pady=10)
Validation function for the date
def validate_date(date_str):
try:
if len(date_str) != 8 or not date_str.isdigit():
return False
year = int(date_str[:4])
month = int(date_str[4:6])
day = int(date_str[6:])
if month < 1 or month > 12:
return False
if month == 12:
last_day = 31
else:
next_month = datetime.date(year, month + 1, 1)
last_day = (next_month - datetime.timedelta(days=1)).day
if day != last_day:
return False
return True
except Exception:
return False
Function to show custom message boxes
def show_message(title, message, color):
message_box = customtkinter.CTkToplevel(app)
center_window(message_box, 300, 150)
message_box.title(title)
message_box.transient(app) # Set to be on top of the main window
message_box.grab_set() # Make the message box modal
label = customtkinter.CTkLabel(message_box, text=message)
label.pack(pady=20)
button = customtkinter.CTkButton(message_box, text="OK", command=message_box.destroy)
button.pack(pady=10)
label.configure(text_color=color)
# Focus handling
def check_and_set_focus():
if message_box.winfo_exists(): # Check if window still exists
message_box.focus_set()
message_box.after(200, check_and_set_focus)
Function to ask the user if they want to create the file and folder
def ask_create_file_and_folder(date_str):
def create():
create_folder_and_file(date_str)
message_box.destroy()
message_box = customtkinter.CTkToplevel(app)
center_window(message_box, 300, 150)
message_box.title("Create File and Folder")
message_box.transient(app) # Set to be on top of the main window
message_box.grab_set() # Make the message box modal
label = customtkinter.CTkLabel(message_box, text="File and folder do not exist.nDo you want to create them?")
label.pack(pady=20)
button_yes = customtkinter.CTkButton(message_box, text="Yes", command=create)
button_yes.pack(side="left", padx=10, pady=10)
button_no = customtkinter.CTkButton(message_box, text="No", command=message_box.destroy)
button_no.pack(side="right", padx=10, pady=10)
# Focus handling
def set_focus():
if message_box.winfo_exists():
message_box.focus_set()
message_box.after(200, set_focus)
Function to create the folder and copy the file from the previous month
def create_folder_and_file(date_str):
folder_path = f"Z:/../{date_str}"
os.makedirs(folder_path, exist_ok=True)
year = int(date_str[:4])
month = int(date_str[4:6])
if month == 1:
previous_month = 12
previous_year = year - 1
else:
previous_month = month - 1
previous_year = year
# Get the last day of the previous month
previous_last_day = (datetime.date(previous_year, previous_month, 1) + datetime.timedelta(days=32)).replace(
day=1) - datetime.timedelta(days=1)
previous_last_day = previous_last_day.day
previous_date_str = f"{previous_year}{previous_month:02d}{previous_last_day:02d}"
previous_file_name = f"Finance_Report_{previous_date_str}.xlsx"
previous_file_path = f"Z:/…/{previous_date_str}/{previous_file_name}"
new_file_name = f"Finance_Report_{date_str}.xlsx"
new_file_path = os.path.join(folder_path, new_file_name)
shutil.copy(previous_file_path, new_file_path)
show_message("Success", f"File created:n{new_file_path}", "green")
Function to check file existence
def check_file_exists(date_str):
folder_path = f"Z:/…/{date_str}"
file_name = f"Finance_Report_{date_str}.xlsx"
file_path = os.path.join(folder_path, file_name)
return os.path.isfile(file_path)
Function to be called on button press
def submit_date():
date_str = date_var.get()
if validate_date(date_str):
if check_file_exists(date_str):
show_message("Success", f"File exists:n{date_str}/Finance_Report_{date_str}.xlsx", "green")
else:
ask_create_file_and_folder(date_str)
else:
show_message("Error", "Invalid date.nPlease enter the last day of the monthnin yyyymmdd format.", "red")
Creates an input box to enter the date and binds it to date_var
date_var = customtkinter.StringVar()
date_entry = customtkinter.CTkEntry(app, textvariable=date_var)
date_entry.pack(padx=10, pady=10)
Creates a submit button that triggers the submit_date function when clicked
submit_button = customtkinter.CTkButton(app, text=”Submit”, command=submit_date)
submit_button.pack(padx=10, pady=10)
Runs the main loop of the application
app.mainloop()
Here is the error:
Exception in Tkinter callback
Traceback (most recent call last):
File “C:Users…AppDataLocalProgramsPythonPython312Libtkinter_init_.py”, line 1948, in call
return self.func(*args)
^^^^^^^^^^^^^^^^
File “C:Users…AppDataLocalProgramsPythonPython312Libtkinter_init_.py”, line 861, in callit
func(*args)
File “C:Users…AppDataLocalProgramsPythonPython312Libtkinter_init_.py”, line 787, in focus_set
self.tk.call('focus', self._w)
_tkinter.TclError: bad window path name “.!ctktoplevel”
João Rodrigues is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.