67

How do I get the 'state' of a Tkinter Checkbutton? By 'state' I mean get whether or not it has a check mark in it or not.

4 Answers 4

78

When you're creating it, it takes a variable keyword argument. Pass it an IntVar from Tkinter. Checking or unchecking the box will set that value contained by var to the corresponding boolean state. This can be accessed as var.get():

checked => var.get()

not checked => not var.get()

>>> root = Tkinter.Tk() >>> var = Tkinter.IntVar() >>> chk = Tkinter.Checkbutton(root, text='foo', variable=var) >>> chk.pack(side=Tkinter.LEFT) >>> var.get() #unchecked 0 >>> var.get() #checked 1 
Sign up to request clarification or add additional context in comments.

5 Comments

Not possible without variable? =(
if its important to you that you can get the value via the widget you can always attach the variable to the widget (something like chk.val = var) and then access it with chk.val.get()
@CiroSantilli烏坎事件2016六四事件法轮功 It's many years later, but I answered a comment you had a long time ago.
Using variables is actually quite powerful. Not only can you use the variable to check the status of the checkbox, but you can also use the variable to SET the value of the checkbox. So, var.set(1) will make sure that the check mark is shown, and var.set(0) will make sure the check is cleared. Further, you can set a trace function for the variable, so that if someone clicks on the checkbox, that function can be triggered. It's all part of the event-driven paradigm. Very powerful stuff.
This is a pain. When I use var_checked.get() from the bind('<Button-1>') handler, it always returns the inverse of the state after the click. And when I try and use var_checked.set(x), it tells me that x has to be str and not bool. Very annoying.
59

If you use the new* ttk module from tkinter, you can read and write checkbutton states without assigning variables.

import tkinter from tkinter import ttk tkwindow = tkinter.Tk() chk = ttk.Checkbutton(tkwindow, text="foo") chk.grid(column=0, row=0) 

Notice that the new checkbox defaults to the "alternate", sometimes called "half-checked", state:

alternate

You can read the current state usinge the .state() method:

>>> print(chk.state()) # half-checked ('alternate',) >>> print(chk.state()) # checked ('selected',) >>> print(chk.state()) # not checked () 

To set the state in code:

chk.state(['selected']) # check the checkbox chk.state(['!selected']) # clear the checkbox chk.state(['disabled']) # disable the checkbox chk.state(['!disabled','selected']) # enable the checkbox and put a check in it! 

And here is a convenient way to check for a specific state:

chk.instate(['selected']) # returns True if the box is checked 

There are two tricky things I've found:

  1. The initial state is "alternate", and this state flag doesn't get cleared when adding a "selected" state flag. So, if you want to toggle your checkbutton in code, you'll first need to clear the "alternate" flag:

    chk.state(['!alternate']) 
  2. If you disable/enable the checkbutton using

    chk.state(['disabled']) chk.state(['!disabled']) 

    then everything works fine. But, if you use these common, alternate methods:

    chk.config(state=tk.DISABLED) chk.config(state=tk.NORMAL) 

    then it reasserts the 'alternate' flag.

    This behavior doesn't happen if you assign a variable to the checkbutton, but then, if you wanted to assign a variable then this answer probably won't help you :)


* ttk became available in Python 2.7 (Tk 8.5). This question talks about the differences between the old standard widgets and the newer, "themed" ones.

3 Comments

AttributeError: 'Checkbutton' object has no attribute 'instate' :(
@AbdullahSaid Hmm, it still works for me. Perhaps you are using the old-style tkinter Checkbutton instead of ttk.Checkbutton?
That alternate flag is still a pain in the ass!
3

bitsmack answer doesn't exactly agree with what I am seeing.

chk.state() returns a tuple which has two elements when selected: ('focus','selected')

import tkinter as tk from tkinter import ttk def p(event): st = ck.state() print (f'is tuple {type(st) is tuple} {len(st)}-----------------------------------------') if 'selected' in st: print ('got selected') for i,pst in enumerate(st) : print(f'{i}, {pst}') root = tk.Tk() root.geometry('200x200+300+200') root.grid_rowconfigure(0, weight = 1) ck = ttk.Checkbutton(root,text = 'tryme') ck.grid() root.bind('<Return>',p) root.mainloop() 

yields this result:

is tuple True 1----------------------------------------

0, alternate is tuple True 2-----------------------------------------

got selected 0, focus 1, selected is tuple True 1-----------------------------------------

0, focus

So, to determine if the checkbox is selected:

if 'selected' in chk.state() 

for alternate:

if 'alternate' in chk.state() 

for not selected:

if not ('selected' in chk.state or 'alternate' in chk.state) 

3 Comments

I know I shouldn't refer to a previous answer, but I cannot add comments at this time
Hello Jim. Welcome to Stack Overflow, and thank you for contributing. I've downvoted this answer because it reads like a response to an existing answer, and a popular solution has already been accepted on this 10-year-old question. Please consider deleting this answer and instead leaving a comment on @bitsmack's answer
Thank you for your comment. I would have commented on the answer, but i lack the reputation to comment. I felt that the problems I encountered following the answer were significant enough to need clarification
0

For getting the state of the checkbutton from a reference to the checkbutton widget:

>>> checkButtonWidget <tkinter.Checkbutton object .!toplevel.!frame.!frame4.!checkbutton23> >>> checkbuttonWidget.getvar(checkbuttonWidget.cget('variable')) 0 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.