assigned to a name, it would normally be garbage collected (destroyed and reclaimed)
by Python immediately after running its pack method.
However, because tkinter emits Tk calls when objects are constructed, the label will be
drawn on the display as expected, even though we haven’t held onto the corresponding
Python object in our script. In fact, tkinter internally cross-links widget objects into a
long-lived tree used to represent the display, so the Label object made during this
statement actually is retained, even if not by our code.*
In other words, your scripts don’t generally have to care about widget object lifetimes,
and it’s OK to make widgets and pack them immediately in the same statement without
maintaining a reference to them explicitly in your code.
But that does not mean that it’s OK to say something like this:
widget = Label(text='hi').pack() # wrong!
...use widget...
This statement almost seems like it should assign a newly packed label to widget, but
it does not do this. In fact, it’s really a notorious tkinter beginner’s mistake. The widget
pack method packs the widget but does not return the widget thus packed. Really,
pack returns the Python object None; after such a statement, widget will be a reference
to None, and any further widget operations through that name will fail. For instance,
the following fails, too, for the same reason:
Label(text='hi').pack().mainloop() # wrong!
Since pack returns None, asking for its mainloop attribute generates an exception (as it
should). If you really want to both pack a widget and retain a reference to it, say this
instead:
widget = Label(text='hi') # OK too
widget.pack()
...use widget...
This form is a bit more verbose but is less tricky than packing a widget in the same
statement that creates it, and it allows you to hold onto the widget for later processing.
It’s probably more common in realistic scripts that perform more complex widget con-
figuration and layouts.
On the other hand, scripts that compose layouts often add some widgets once and for
all when they are created and never need to reconfigure them later; assigning to long-
lived names in such programs is pointless and unnecessary.
- Ex-Tcl programmers in the audience may be interested to know that, at least at the time I was writing this
footnote, Python not only builds the widget tree internally, but uses it to automatically generate widget
pathname strings coded manually in Tcl/Tk (e.g., .panel.row.cmd). Python uses the addresses of widget class
objects to fill in the path components and records pathnames in the widget tree. A label attached to a
container, for instance, might have an assigned name such as .8220096.8219408 inside tkinter. You don’t have
to care, though. Simply make and link widget objects by passing parents, and let Python manage pathname
details based on the object tree. See the end of this chapter for more on Tk/tkinter mappings.
378 | Chapter 7: Graphical User Interfaces