Reputation: 96
I want to change a TKinter.Checkbutton
's value when it is being clicked.
The button is a Checkbutton
and I use an IntVar
to track/change its value.
In the following example I just have one button and I want it to change state back to 0 whenever we click on it (it can sound stupid in this case but I am trying to solve an other more complex case where more buttons change values).
The value is actually updated but the button's appearance does not change until the mouse leaves what seems to be the button's area.
Here is the minimal example :
try :
import Tkinter as tk
except ImportError as e:
import tkinter as tk
root = tk.Tk()
val = tk.IntVar(root)
val.trace("w", lambda a, b, c: val.set(0))
button = tk.Checkbutton(root, text="button", variable=val)
button.pack()
root.mainloop()
To reproduce :
launch the application
click on the button but keep your mouse on it (the button will change its appearance to selected)
leave the button's area (the button finally changes its appearance to unselected)
Why does it wait for the mouse to leave its area ? How could I force the button's appearance to change instantly ?
Thanks
EDIT :
It looks like using ttk.Checkbutton
does not have this issue. Still it does not explain why the original button behave like it does and how to have the desired behaviour with tk
buttons.
Upvotes: 0
Views: 359
Reputation: 9621
Setting a variable from within a write trace on the same variable is extremely problematic - this would be an infinite recursion, if Tcl didn't automatically disable traces during the execution of a trace. The widget's updating of its displayed value is itself handled by a trace on the variable, so it's not surprising that the display gets out of sync - what's surprising is that it gets back into sync later, I have no idea how that happens.
If you must do this from a write trace (rather than the command=
option as has been suggested, which happens when the variable is in a more stable state), you need to defer the change slightly: root.after(1, var.set, 0)
perhaps.
Upvotes: 1