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_interiorcontains 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
Toplevelclass is implemented with a Tk toplevel, mega-widgets in theToplevelclass have their own toplevel window. This class is used to create dialog boxes and other pop-up windows.Example
Suppose we want to create aMessageInfomega-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::Toplevelbase 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
centerOnScreenthat 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_initializemethod. Each derived class must invoke theitk_initializemethod 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
keepandrenamestatements 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 createMessageInfomega-widgets. This adheres to the Tk convention for widget creation commands.