part.config(bd=2, relief=GROOVE) # or pass configs to Demo()
part.pack(side=LEFT, expand=YES, fill=BOTH) # grow, stretch with window
Because the demo classes use their **options arguments to support constructor argu-
ments, though, we could configure at creation time, too. For example, if we change
this code as follows, it produces the slightly different composite window captured in
Figure 8-33 (stretched a bit horizontally for illustration, too; you can run this as
demoAll-frm-ridge.py in the examples package):
def addComponents(root):
for demo in demoModules:
module = __import__(demo) # import by name string
part = module.Demo(root, bd=6, relief=RIDGE) # attach, config instance
part.pack(side=LEFT, expand=YES, fill=BOTH) # grow, stretch with window
Because the demo classes both subclass Frame and support the usual construction
argument protocols, they become true widgets—specialized tkinter frames that imple-
ment an attachable package of widgets and support flexible configuration techniques.
Figure 8-33. demoAll_frm: configure when constructed
As we saw in Chapter 7, attaching nested frames like this is really just one way to reuse
GUI code structured as classes. It’s just as easy to customize such interfaces by sub-
classing rather than embedding. Here, though, we’re more interested in deploying an
existing widget package than changing it, so attachment is the pattern we want. The
next two sections show two other ways to present such precoded widget packages to
users—in pop-up windows and as autonomous programs.
Running GUI Code Three Ways | 475