def makeform(root, fields):
form = Frame(root) # make outer frame
left = Frame(form) # make two columns
rite = Frame(form)
form.pack(fill=X)
left.pack(side=LEFT)
rite.pack(side=RIGHT, expand=YES, fill=X) # grow horizontal
variables = []
for field in fields:
lab = Label(left, width=5, text=field) # add to columns
ent = Entry(rite)
lab.pack(side=TOP)
ent.pack(side=TOP, fill=X) # grow horizontal
var = StringVar()
ent.config(textvariable=var) # link field to var
var.set('enter here')
variables.append(var)
return variables
if name == 'main':
root = Tk()
vars = makeform(root, fields)
Button(root, text='Fetch', command=(lambda: fetch(vars))).pack(side=LEFT)
Quitter(root).pack(side=RIGHT)
root.bind('
root.mainloop()
Except for the fact that this script initializes input fields with the string 'enter here',
it makes a window virtually identical in appearance and function to that created by the
script entry2 (see Figures 8-23 and 8-24). For illustration purposes, the window is laid
out differently—as a Frame containing two nested subframes used to build the left and
right columns of the form area—but the end result is the same when it is displayed on
screen (for some GUIs on some platforms, at least: see the note at the end of this section
for a discussion of why layout by rows instead of columns is generally preferred).
The main thing to notice here, though, is the use of StringVar variables. Instead of using
a list of Entry widgets to fetch input values, this version keeps a list of StringVar objects
that have been associated with the Entry widgets, like this:
ent = Entry(rite)
var = StringVar()
ent.config(textvariable=var) # link field to var
Once you’ve tied variables in this way, changing and fetching the variable’s value:
var.set('text here')
value = var.get()
Message and Entry | 455