Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multiple Toplevel windows 1

Status
Not open for further replies.

sh00der

Technical User
Jul 15, 2003
58
CA
Hi, please help, I am writing a GUI that opens a toplevel dialog window when certain canvas items are double-clicked. I need to be able to have multiple toplevel windows open at once, each with their own set of variables. For example, each toplevel will have an exit button that destroys only its own toplevel window. It seems that variables assigned to widgets within the toplevel, like entries, have to be global? Am I missing something here?
 
Theres nothing to stop you from creating more than 1 toplevel dialog. And as far as your new toplevel dialog having its own buttons, just create new buttons for it. Heres an example of how you can have multiple toplevel dialogs.

toplevel .top
frame .top.frame
button .top.frame.button -text "exit" -command "destroy .top"
pack .top.frame.button
pack .top.frame

toplevel .top2
frame .top2.frame
button .top2.frame.button -text "exit" -command "destroy .top2"
pack .top2.frame.button
pack .top2.frame

toplevel .top3
frame .top3.frame
button .top3.frame.button -text "exit" -command "destroy .top3"
pack .top3.frame.button
pack .top3.frame



the example above creates three separate toplevel dialogs each with thie own buttons. Just remember that the widgets on each toplevel need to be kept separate and named according to the toplevel they belong to.
 
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
 
Thanks for the fast response and help. Seeing as there will be a large amount of entry widgets in my toplevels I was hoping that I wouldn't have to use global variables for them all. I'll just have to name them carefully so I can keep track of them, thanks again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top