The Toplevel class inherits everything from the Archetype class, and adds a Tk toplevel called the "hull" component to represent the body of the mega-widget. The window class name for the hull is set to the most-specific class name for the mega-widget. The protected variableitk_interior
contains the window path name for the "hull" component. Derived classes specialize this widget by packing other widget components into the hull.Since the hull for the
Toplevel
class is implemented with a Tk toplevel, mega-widgets in theToplevel
class have their own toplevel window. This class is used to create dialog boxes and other pop-up windows.Example
Suppose we want to create aMessageInfo
mega-widget class that acts as a pop-up notice window. It displays a message which the user can dismiss by pressing the "Dismiss" button. If we had such a widget, we might use it like this:
messageinfo .m -background blue -foreground white \ -message "File not found:\n/usr/local/bin/foo"and it would look like this:
Each time a new widget is created, the constructor is invoked automatically to create the internal component widgets. The "hull" component is created automatically by the
itk::Toplevel
base class. Other components can be packed into this. Each component must be created using the "itk_component add
" method, as shown below. This method creates a component widget, gives it a symbolic name, and merges its options into the composite list for the mega-widget. Once a component has been created like this, its window path name can be referenced via its symbolic name as "$itk_component(name)
".The methods in the mega-widget class define the operations that the widget will respond to. In this example, there is a protected method
centerOnScreen
that is used internally to bring up the window in the middle of the screen.
option add *MessageInfo.title "Notice" widgetDefault class MessageInfo { inherit itk::Toplevel constructor {args} { itk_component add dismiss { button $itk_interior.dismiss -text "Dismiss" \ -command "destroy $itk_component(hull)" } pack $itk_component(dismiss) -side bottom -pady 4 itk_component add separator { frame $itk_interior.sep -height 2 -borderwidth 1 -relief sunken } pack $itk_component(separator) -side bottom -fill x -padx 4 itk_component add icon { label $itk_interior.icon -bitmap info } pack $itk_component(icon) -side left -padx 8 -pady 8 itk_component add infoFrame { frame $itk_interior.info } pack $itk_component(infoFrame) -side left -expand yes \ -fill both -padx 4 -pady 4 itk_component add message { label $itk_interior.mesg -width 20 } { usual rename -text -message message Text } pack $itk_component(message) -expand yes -fill both eval itk_initialize $args after idle [code $this centerOnScreen] } protected method centerOnScreen {} { update idletasks set wd [winfo reqwidth $itk_component(hull)] set ht [winfo reqheight $itk_component(hull)] set x [expr ([winfo screenwidth $itk_component(hull)]-$wd)/2] set y [expr ([winfo screenheight $itk_component(hull)]-$ht)/2] wm geometry $itk_component(hull) +$x+$y } } usual MessageInfo { keep -background -cursor -foreground -font keep -activebackground -activeforeground -disabledforeground keep -highlightcolor -highlightthickness } proc messageinfo {pathName args} { uplevel MessageInfo $pathName $args }
Notice how the constructor takes widget configuration options as an "args
" list, and passes these arguments to theitk_initialize
method. Each derived class must invoke theitk_initialize
method in this manner within its constructor , so that all options are properly integrated and initialized in the composite list.It is a good idea to include the following things along with the mega-widget class definition:
- Default option settings for the mega-widget. These should be set with the "widgetDefault" priority.
- Declarations for "usual" option-handling code. This is a series of
keep
andrename
statements that says how the options should be handled if this mega-widget is included as a component of another mega-widget. It is usually a good idea to keep generic options like "-background
" and "-font
". Options like "-text
" and "-command
" that make each widget unique should be ignored for the "usual" set.
- A procedure with the same name as the mega-widget class, but with all lower-case letters, that can be used to create mega-widgets. In the example above, the "
messageinfo
" command can be used to createMessageInfo
mega-widgets. This adheres to the Tk convention for widget creation commands.