CustomTkinter
CustomTkinter copied to clipboard
CTkOptionMenu variable_callback issue
When the option menu is deleted and then recreated using the same variable it throws an error.
customtkinter: 4.6.3
IOS: Windows 10
Steps To Reproduce
- Run the below code in a python file.
- Click on the dropdown menu and select an option.
- Console throws the error
Observed Results
- Defining the variable inside the load function fixes the issue.
- The issue only occurs when the widget is deleted
Code:
from customtkinter import CTk, CTkOptionMenu
from tkinter import StringVar
root = CTk()
TEST = StringVar()
TEST.set("item1")
def clear():
for c in root.winfo_children():
c.destroy()
def load():
values = ["item1", "item2", "item3"]
test = CTkOptionMenu(root, values=values, variable=TEST)
test.pack()
load() # Works properly
clear()
load() # raises the issue
root.mainloop()
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\1589l\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\1589l\AppData\Local\Programs\Python\Python310\lib\site-packages\customtkinter\widgets\ctk_optionmenu.py", line 283, in variable_callback
self.text_label.configure(text=self.current_value)
File "C:\Users\1589l\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1675, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\1589l\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1665, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!ctkoptionmenu.!label"
Thanks for reporting this. I forgot to remove the callback remove the write-callback from the variable when destroying the widget. It will be fixed in the next version 5.0.0, which will be released soon.
Fixed with version 5.0.0.
Hi Tom, I'm experiencing alike issue right now, but the difference is that widget throwing exception error is CTkEntry. I'm doing dynamic UI and when trying to destroy widget, I want to empty out any text in textvariable stringVar stored, so I can reuse the same variable if widget is created again. After destroying a widget, textvariable can't be .set('') without error, while .set('%anything%') doesn't throw exceptions.
Code:
from customtkinter import CTk, CTkEntry, CTkComboBox
from tkinter import StringVar
root = CTk()
TEST = StringVar()
def clear():
for c in root.winfo_children():
c.destroy()
def load():
test = CTkEntry(root, textvariable=TEST)
test.pack()
TEST.set("") #no error
load()
TEST.set("") #no error
clear()
TEST.set("") #throws error, but still works, stringvar changes to ''
TEST.set("%") #no error
root.mainloop()
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\site-packages\customtkinter\windows\widgets\ctk_entry.py", line 121, in _textvariable_callback
self._activate_placeholder()
File "C:\Program Files\Python311\Lib\site-packages\customtkinter\windows\widgets\ctk_entry.py", line 299, in _activate_placeholder
if self._entry.get() == "" and self._placeholder_text is not None and (self._textvariable is None or self._textvariable == ""):
^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\tkinter\__init__.py", line 3099, in get
return self.tk.call(self._w, 'get')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: invalid command name ".!ctkentry.!entry"