Check buttons and variables
When I first studied check buttons, my initial reaction was: why do we need tkinter
variables here at all when we can register button-press callbacks? Linked variables may
seem superfluous at first glance, but they simplify some GUI chores. Instead of asking
you to accept this blindly, though, let me explain why.
Keep in mind that a Checkbutton’s command callback will be run on every press, whether
the press toggles the check button to a selected or a deselected state. Because of that,
if you want to run an action immediately when a check button is pressed, you will
generally want to check the button’s current value in the callback handler. Because
there is no check button “get” method for fetching values, you usually need to inter-
rogate an associated variable to see if the button is on or off.
Moreover, some GUIs simply let users set check buttons without running command call-
backs at all and fetch button settings at some later point in the program. In such a
scenario, variables serve to automatically keep track of button settings. The demo
Check script’s report method represents this latter approach.
Of course, you could manually keep track of each button’s state in press callback
handlers, too. Example 8-23 keeps its own list of state toggles and updates it manually
on command press callbacks.
Example 8-23. PP4E\Gui\Tour\demo-check-manual.py
check buttons, the hard way (without variables)
from tkinter import *
states = [] # change object not name
def onPress(i): # keep track of states
states[i] = not states[i] # changes False->True, True->False
root = Tk()
for i in range(10):
chk = Checkbutton(root, text=str(i), command=(lambda i=i: onPress(i)) )
chk.pack(side=LEFT)
states.append(False)
root.mainloop()
print(states) # show all states on exit
The lambda here passes along the pressed button’s index in the states list. Otherwise,
we would need a separate callback function for each button. Here again, we need to
use a default argument to pass the loop variable into the lambda, or the loop variable
will be its value on the last loop iteration for all 10 of the generated functions (each
press would update the tenth item in the list; see Chapter 7 for background details on
this). When run, this script makes the 10–check button display in Figure 8-27.
460 | Chapter 8: A tkinter Tour, Part 1