Closed LJDrakeley closed 6 months ago
Show full code, please
Hi Anonymous6598, unfortunately I cannot show the code (and the size of the project is more than 2500 lines long anyway). However, that is the full extent of the error message that occurs when closing the window. I do not have any custom closing method if that helps. If this cannot be resolved without the code it's okay but I'm curious for a solution nonetheless. Thanks!
Without code its almost impossible to say what's wrong, anyway, the only thing i recommend is, to make sure that your window desrutruction is don properly. Means, if you destroy the window and afterwards try to access something from customtkinter it can lead to an error like this. Hope you find a solution 😸
Thanks @JanPanthera for support. Yes, without code it's impossible to understand issue.
I have this exact issue and I also need help with this, here is an example:
import customtkinter as ctk
root = ctk.CTk()
root.mainloop()
root = ctk.CTk()
root.mainloop()
In the example above, to get the error you have to destroy the window. Then it will try to create a new root and it fails.
The event occurs when the user destroys the window and creates a new root window in any way, (eg. it happens when root.destroy()
is called before the last root definition through a button or something.)
Have you tried to delay the second creation, maybe the internal code is still cleaning up while you are trying to create a new one?
Have you tried to delay the second creation, maybe the internal code is still cleaning up while you are trying to create a new one?
Okay, here is the new code then:
import customtkinter as ctk
from time import sleep
root = ctk.CTk()
root.mainloop()
sleep(5)
root = ctk.CTk()
root.mainloop()
It still raises this error:
invalid command name "2212570062528update"
while executing
"2212570062528update"
("after" script)
yeah thats odd, sorry i don't know, this is something for the actual dev then
here is solution to your problem:
import customtkinter as ctk
from time import sleep
root_1 = ctk.CTk()
root_1.protocol("WM_DELETE_WINDOW", root_1.destroy())
root_1.mainloop()
sleep(5)
root_2 = ctk.CTk()
root_2.protocol("WM_DELETE_WINDOW", root_2.destroy())
root_2.mainloop()
```python import customtkinter as ctk from time import sleep root_1 = ctk.CTk() root_1.protocol("WM_DELETE_WINDOW", root_1.destroy()) root_1.mainloop() sleep(5) root_2 = ctk.CTk() root_2.protocol("WM_DELETE_WINDOW", root_2.destroy()) root_2.mainloop()
That doesn't work, this is the error it produces now:
Traceback (most recent call last):
File "C:\Users\username\PycharmProjects\project\TEST.py", line 6, in <module>
root_1.protocol("WM_DELETE_WINDOW", root_1.destroy())
File "C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 2253, in wm_protocol
return self.tk.call(
^^^^^^^^^^^^^
_tkinter.TclError: can't invoke "wm" command: application has been destroyed
```python import customtkinter as ctk from time import sleep root_1 = ctk.CTk() root_1.protocol("WM_DELETE_WINDOW", root_1.destroy()) root_1.mainloop() sleep(5) root_2 = ctk.CTk() root_2.protocol("WM_DELETE_WINDOW", root_2.destroy()) root_2.mainloop()
That doesn't work, this is the error it produces now:
Traceback (most recent call last): File "C:\Users\username\PycharmProjects\project\TEST.py", line 6, in <module> root_1.protocol("WM_DELETE_WINDOW", root_1.destroy()) File "C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 2253, in wm_protocol return self.tk.call( ^^^^^^^^^^^^^ _tkinter.TclError: can't invoke "wm" command: application has been destroyed
Try this :
import customtkinter as ctk
from time import sleep
root_1 = ctk.CTk()
root_1.protocol("WM_DELETE_WINDOW", root_1.destroy)
root_1.mainloop()
sleep(5)
root_2 = ctk.CTk()
root_2.protocol("WM_DELETE_WINDOW", root_2.destroy)
root_2.mainloop()
Try catching it with try and except
```python import customtkinter as ctk from time import sleep root_1 = ctk.CTk() root_1.protocol("WM_DELETE_WINDOW", root_1.destroy()) root_1.mainloop() sleep(5) root_2 = ctk.CTk() root_2.protocol("WM_DELETE_WINDOW", root_2.destroy()) root_2.mainloop()
That doesn't work, this is the error it produces now:
Traceback (most recent call last): File "C:\Users\username\PycharmProjects\project\TEST.py", line 6, in <module> root_1.protocol("WM_DELETE_WINDOW", root_1.destroy()) File "C:\Users\username\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 2253, in wm_protocol return self.tk.call( ^^^^^^^^^^^^^ _tkinter.TclError: can't invoke "wm" command: application has been destroyed
Try this :
import customtkinter as ctk from time import sleep root_1 = ctk.CTk() root_1.protocol("WM_DELETE_WINDOW", root_1.destroy) root_1.mainloop() sleep(5) root_2 = ctk.CTk() root_2.protocol("WM_DELETE_WINDOW", root_2.destroy) root_2.mainloop()
You made mistake. destroy()
is missing. Therefore function won't work.
I forgot to put lambda
here is solution:
import customtkinter as ctk
from time import sleep
root_1 = ctk.CTk()
root_1.protocol("WM_DELETE_WINDOW", lambda: root_1.destroy())
root_1.mainloop()
root_2 = ctk.CTk()
root_2.protocol("WM_DELETE_WINDOW", lambda: root_2.destroy())
root_2.mainloop()
I forgot to put
lambda
here is solution:import customtkinter as ctk from time import sleep root_1 = ctk.CTk() root_1.protocol("WM_DELETE_WINDOW", lambda: root_1.destroy()) root_1.mainloop() root_2 = ctk.CTk() root_2.protocol("WM_DELETE_WINDOW", lambda: root_2.destroy()) root_2.mainloop()
That still produces this error:
invalid command name "2742723926720update"
while executing
"2742723926720update"
("after" script)
The numbers in the error change every time the program is run for some reason. (Maybe the CTk class has codes for each function??)
And because this is a simple example, the error is not long like OP showed.
final solution:
import customtkinter as ctk, sys
from time import sleep
def exit():
root_1.withdraw()
root_2 = ctk.CTk()
root_2.protocol("WM_DELETE_WINDOW", lambda: sys.exit())
root_2.mainloop()
root_1 = ctk.CTk()
root_1.protocol("WM_DELETE_WINDOW", lambda: exit())
root_1.mainloop()
Without code its almost impossible to say what's wrong, anyway, the only thing i recommend is, to make sure that your window desrutruction is don properly. Means, if you destroy the window and afterwards try to access something from customtkinter it can lead to an error like this. Hope you find a solution 😸
Understandable! I apologize I cannot give the code, I was hoping it was a more widespread issue that others have commonly seen. Thank you all for your time and efforts. I hope VillainousSsnake finds a solution to their similar issue. It is odd that the window delete protocol must be explicitly stated for correct closing?
final solution:
import customtkinter as ctk, sys from time import sleep def exit(): root_1.withdraw() root_2 = ctk.CTk() root_2.protocol("WM_DELETE_WINDOW", lambda: sys.exit()) root_2.mainloop() root_1 = ctk.CTk() root_1.protocol("WM_DELETE_WINDOW", lambda: exit()) root_1.mainloop()
That works! Thanks for helping me, I was about to put my entire app on hold because of this bug but now I can continue development!
Your welcome dude
Without code its almost impossible to say what's wrong, anyway, the only thing i recommend is, to make sure that your window desrutruction is don properly. Means, if you destroy the window and afterwards try to access something from customtkinter it can lead to an error like this. Hope you find a solution 😸
Understandable! I apologize I cannot give the code, I was hoping it was a more widespread issue that others have commonly seen. Thank you all for your time and efforts. I hope VillainousSsnake finds a solution to their similar issue. It is odd that the window delete protocol must be explicitly stated for correct closing?
Yes, it is needed.
@LJDrakeley we don't need your entire source code, that would actually be worse. What we need is a Minimal, Reproducible Example (MRE). If you can take your application, strip it down to the minimal set of statements that reproduce the bug, then people can use that to diagnose the issue. Without an MRE, any number of things could be causing it.
@PhilipNelson5 I have finally been able to isolate the problem. I just started a new project and I noticed that by creating a method that destroys some window, and then creates another, causes the error.
Here is an example:
import customtkinter as ctk
class WindowClass(ctk.CTk):
def __init__(self, parent):
super().__init__()
self.parent = parent
button = ctk.CTkButton(master=self,
text='destroy',
command=lambda: self.parent.open_new_window(self))
button.pack()
class MainClass:
def __init__(self):
window = WindowClass(parent=self)
window.mainloop()
def open_new_window(self, some_window):
some_window.destroy()
new_window = WindowClass(parent=self)
new_window.mainloop()
if __name__ == "__main__":
app = MainClass()
Thanks in advance!
There is a print statement in \destroy
sequence. Uncommenting it provides some insight. The window is trying to execute commands that have been deleted.
- Tkinter: deleted command 2489637091072_on_enter
- Tkinter: deleted command 2489637091328_on_leave
- Tkinter: deleted command 2489637091584_clicked
- Tkinter: deleted command 2489615068352_on_enter
- Tkinter: deleted command 2489615068800_on_leave
- Tkinter: deleted command 2489615069120_clicked
- Tkinter: deleted command 2489615069632_clicked
- Tkinter: deleted command 2489637089344_update_dimensions_event
- Tkinter: deleted command 2489615088832_click_animation
- Tkinter: deleted command tkerror
- Tkinter: deleted command exit
- Tkinter: deleted command 2489614969856destroy
- Tkinter: deleted command 2489637086144_update_dimensions_event
- Tkinter: deleted command 2489637086400_focus_in_event
- Tkinter: deleted command 2489615069952check_dpi_scaling
- Tkinter: deleted command 2489615057856update
invalid command name "2489615057856update"
while executing
"2489615057856update"
("after" script)
invalid command name "2489615069952check_dpi_scaling"
while executing
"2489615069952check_dpi_scaling"
("after" script)
invalid command name "2489615088832_click_animation"
while executing
"2489615088832_click_animation"
("after" script)
I think the problem is creating multiple Tk instances. From what I've read, it can be done, however it is tricky to manage. A simpler path is to create one Tk instance and use multiple TopWindows. Here is a working example:
from typing import Tuple
import customtkinter as CTk
class App(CTk.CTk):
def __init__(self, fg_color: str | Tuple[str, str] | None = None, **kwargs):
super().__init__(fg_color, **kwargs)
self.withdraw()
self.window = Window(master=self)
def new_window(self):
self.window.destroy()
self.window = Window(master=self)
class Window(CTk.CTkToplevel):
def __init__(self, master):
super().__init__(master=master)
self.geometry("200x80")
button = CTk.CTkButton(
master=self,
text="destroy",
command=lambda: self.master.new_window(),
)
button.pack(padx=25, pady=25)
self.protocol("WM_DELETE_WINDOW", self.master.destroy)
if __name__ == "__main__":
app = App()
app.mainloop()
The application immediately hides the man window which owns the eventloop. Then it creates a new TopWindow. self.protocol("WM_DELETE_WINDOW", self.master.destroy)
destroys the main window when you press the X on one of the TopLevel windows to stop the eventloop.
Great solution!
Thank you, I will be implementing this method from now on.
Awesome, if that resolves your problem, you can close this issue.
When closing my custom tkinter window, I receive the following error message:
invalid command name "2462417235584update" while executing "2462417235584update" ("after" script) invalid command name "2462162051648check_dpi_scaling" while executing "2462162051648check_dpi_scaling" ("after" script)
I do not use any custom methods that check for dpi scaling, "update" or any "after" methods. Is this an issue with the package? Thank you in advance.