CustomTkinter icon indicating copy to clipboard operation
CustomTkinter copied to clipboard

CTkOptionMenu variable_callback issue

Open legopitstop opened this issue 3 years ago • 1 comments
trafficstars

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

  1. Run the below code in a python file.
  2. Click on the dropdown menu and select an option.
  3. 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"

legopitstop avatar Sep 20 '22 23:09 legopitstop

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.

TomSchimansky avatar Oct 07 '22 14:10 TomSchimansky

Fixed with version 5.0.0.

TomSchimansky avatar Dec 02 '22 12:12 TomSchimansky

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"

Lutheine avatar Sep 11 '23 09:09 Lutheine