No, you don't seem to be missing anything. Just remember that each widget must have a unique hierarchical name. A common technique is to use the value of a global counter variable as part of the name of the parent widget you create, incrementing the counter variable each time you create a new window.
As for associating variables with widgets, like a
-textvariable for an entry widget, you're almost correct. The variable must be a persistent variable (typically global, but it could also be a namespace variable), not a local variable. You can use either a scalar variable, or an
array element. For example, it's quite legal to do something like this:
Code:
entry .first -textvariable name(first)
entry .last -textvariable name(last)
So, you could combine these techniques. Here's a quick example:
Code:
# The global notesInfo array will contain information
# for all dynamically-created windows.
# Initialize the counter stored in the "num" element
set notesInfo(num) 0
proc CreateNote {} {
global notesInfo
# Increment the counter and append its value to
# the rest of the name for our new toplevel
set w [toplevel .top[incr notesInfo(num)] ]
# Initialize any per-window information required
# by the application.
set notesInfo($w-state) "Created"
# Create a couple of entry widgets, associating
# their -textvariable values to elements in our
# notesInfo array.
entry $w.first -textvariable notesInfo($w-first)
entry $w.last -textvariable notesInfo($w-last)
pack $w.first $w.last -fill x -padx 4 -pady 4
# Create a destroy button that destroys this window.
button $w.close -text "Close" -command [list DestroyNote $w]
pack $w.close -padx 4 -pady 4
# Override the default handler that's invoked when the
# window manager attempts to destroy this window (for
# example, when the user clicks the "X" in the window's
# titlebar). We'll call our own procedure to clean up
# all data associated with the window before destroying
# it.
wm protocol $w WM_DELETE_WINDOW [list DestroyNote $w]
# Return the name of the toplevel widget
return $w
}
proc DestroyNote {w} {
global notesInfo
# Delete the toplevel and all of its children. You
# must delete the widgets before their associated
# -textvariables, or else Tcl recreates the
# -textvariables.
destroy $w
# Delete all array elements associated with the
# given window. Note that the "array unset" command
# was introduced in Tcl 8.3.
array unset notesInfo $w-*
}
- Ken Jones, President, ken@avia-training.com
Avia Training and Consulting,
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax