Home > Back-end >  How can I determine whether a checkbutton is checked without assigning an IntVar?
How can I determine whether a checkbutton is checked without assigning an IntVar?

Time:10-02

I would like to check the state of a checkbutton without assigning an IntVar.

I do not want to associate redundant variables to every checkbox in my program unless it's necessary. It seems this should be possible since tkinter records the state of a checkbutton whether or not I assign an IntVar.

The code below makes a menu with 3 checkable options, each of which is assigned a IntVar. The IntVars update as expected based on whether the options are checked. I tried determining whether options were checked using entrycget, which gave the errors noted in the code.

Is there a more Pythonic way of doing this?

from tkinter import *
root = Tk()
root.geometry("200x400")

#This routine should print '1' if option 0 is checked and "0" when not checked
def menucallback():
               
    print(f"Checked = {menuCheckbuttonStates[0].get()}") #works correctly

    #this prints "active" if the mouse was over option 0 regardless of checked state
    print(mb.menu.entrycget(0, "state"))

    #printing checked option 0 using the value of entrycget should show the underlying IntVar,
    #but it throws an error '_tkinter.TclError: unknown option "-value" '
    #var=(mb.menu.entrycget(0, "value"))

    #printing checked option 0 using the variable of entrycget does not work as I expected            
    var=(mb.menu.entrycget(0, "variable"))
    print(var) # prints "PY_VAR0"          
    #print(var.get()) #throws error "AttributeError: '_tkinter.Tcl_Obj' object has no attribute 'get'"

#setup a menubutton with a menu
mb=Menubutton(root, text="Expand Menu", relief=RAISED)
mb.menu=Menu(mb, tearoff=0)
mb["menu"]=mb.menu

#initialize a variable array to hold checkbutton states
menuCheckbuttonStates=[] 

#add checkable options to the menu
options=['option 0','option 1','option 2']            
for x in options:
    y=IntVar()
    menuCheckbuttonStates.append(y)
    mb.menu.add_checkbutton(label=x, variable=y, onvalue=1, offvalue=0, command=menucallback)

mb.pack()
root.mainloop()

CodePudding user response:

I do not want to associate redundant variables to every checkbox in my program unless it's necessary.

The variables aren't redundant. The checkbuttons will have variables associated with them whether or not you explicitly assign it.

You don't have to give it an explicit variable name, though. You can ask tkinter to give you the variable name, and then use the getvar method to get the value of that variable.

Here's a simplified version of your callback that prints out the values of all of the checkbuttons. It leverages the fact that you can look up the value of a menuitem by the menuitem text.

def menucallback():
    for label in ["option 0", "option 1", "option 2"]:
        varname=self.mb.menu.entrycget(label, "variable")
        print(f"{label} = {self.getvar(varname)}")
  • Related