I am trying to get the value of a Tkinter.Checkbutton
‘s variable using .get()
, but I get an error.
import Tkinter as tk
class myApp(tk.Tk):
def __init__(self, parent):
tk.Tk.__init__(self, parent)
self.parent = parent
self.grid()
self.var = tk.IntVar()
self.cb = tk.Checkbutton(self.parent, variable=self.var)
self.cb.bind('<Button-1>', self.useValue)
print self.var.get() # works
print self.cb.get() # does not work
print self.cb.cget('variable') # prints something like PYNUMVAR1
print self.cb.cget('variable').get() # error I mention below
print self.cb.var.get() # error
print self.cb.val.get() # error
def useValue(self, event):
print event.widget.cget('variable').get()) # why not?
if __name__ == '__main__':
runit = myApp(None)
runit.mainloop()
I tried plenty of combinations of everything I’ve seen all over stackoverflow and other tutorial sites. The error I get is:
AttributeError: '_tkinter.Tcl_Obj' object has no attribute 'get'
It should be an IntVar
, not a _tkinter.Tcl_Obj
object, which doesn’t have a get
attribute, when I try, it raises an attribute error on self.var
like this:
print self.var.crumpet()
The console lets me know that it is also that type of object. (It did this on my first experiment, but I cannot get it to recreate this error message on the IntVar
instance in the example code above, so I think this might be wrong.)
I know I can just use get()
on self.var
, but if I’m passing the widget to a callback function via the event parameter, I would like to be able to get the value of it.
How can I get the value of the Checkbutton
without having to do anything with the variable? Should I avoid assigning it a variable?
Advertisement
Answer
print event.widget.cget(‘variable’).get()) # why not?
It’s simply a limitation of tkinter. Conceptually it should work, and you can do the equivalent in tcl/tk, but it won’t work in tkinter.
In other words, it’s a bug, either in the design of tkinter or it’s implementation, I’m not sure which.
How the hell can I get the value of the Checkbutton without having to do anything with the variable? Should I avoid assigning it a variable?
A simple but effective solution is to attach a reference to the widget:
class myApp(tk.Tk):
def __init__( ):
self.cb.var = self.var
def useValue(self, event):
print event.widget.var.get()
Another solution is the under-documented getvar
method which takes a tcl variable name as an argument and returns the value.
For example:
def useValue(self, event):
widget = event.widget
varname = str(widget.cget("variable"))
print widget.getvar(varname)
Note: binding to <Button-1>
means your callback will be called before the checkbutton is set or unset. It will always show the previous value. Either bind to <ButtonRelease-1>
, or put a trace on the variable. The latter is preferable since a binding on <ButtonRelease-1>
won’t fire if the user changes the checkbutton via the keyboard.