itclwidget
-
NAME
- itcl::widget — create a widget class of objects
- WARNING!
- SYNOPSIS
- DESCRIPTION
- WIDGET DEFINITIONS
- WIDGET USAGE
- OBJECT USAGE
- BUILT-IN METHODS
-
objName cget option
- objName configure ?option? ?value option value ...?
- objName isa widgetName
- objName info option ?args...?
- objName configure ?option? ?value option value ...?
- CHAINING METHODS/PROCS
- AUTO-LOADING
- C PROCEDURES
- KEYWORDS
Name
itcl::widget — create a widget class of objectsWarning!
This is new functionality in [incr Tcl] where the API can still change!!Synopsis
itcl::widget widgetName {inherit baseWidget ?baseWidget...?
constructor args ?init? body
destructor body
public method name ?args? ?body?
protected method name ?args? ?body?
private method name ?args? ?body?
public proc name ?args? ?body?
protected proc name ?args? ?body?
private proc name ?args? ?body?
public variable varName ?init? ?config?
protected variable varName ?init? ?config?
private variable varName ?init? ?config?
public common varName ?init?
protected common varName ?init?
private common varName ?init?
public command ?arg arg ...?
protected command ?arg arg ...?
private command ?arg arg ...?
<delegation info> see delegation page
<option info> see option page
set varName ?value?
array option ?arg arg ...?
}
widgetName objName ?arg arg ...?
objName method ?arg arg ...?
widgetName::proc ?arg arg ...?
Description
One of the fundamental constructs in [incr Tcl] is the widget definition. A widget is like a class with some additional features. Each widget acts as a template for actual objects that can be created. The widget itself is a namespace which contains things common to all objects. Each object has its own unique bundle of data which contains instances of the "variables" defined in the widget definition. Each object also has a built-in variable named "this", which contains the name of the object. Widgets can also have "common" data members that are shared by all objects in a widget.Two types of functions can be included in the widget definition. "Methods" are functions which operate on a specific object, and therefore have access to both "variables" and "common" data members. "Procs" are ordinary procedures in the widget namespace, and only have access to "common" data members.
If the body of any method or proc starts with "@", it is treated as the symbolic name for a C procedure. Otherwise, it is treated as a Tcl code script. See below for details on registering and using C procedures.
A widget can only be defined once, although the bodies of widget methods and procs can be defined again and again for interactive debugging. See the body and configbody commands for details.
Each namespace can have its own collection of objects and widgets. The list of widgets available in the current context can be queried using the "itcl::find widgets" command, and the list of objects, with the "itcl::find objects" command.
A widget can be deleted using the "delete widget" command. Individual objects can be deleted using the "delete object" command.
Widget definitions
The widget definition is evaluated as a series of Tcl statements that define elements within the widget. The following widget definition commands are recognized:
Widget usage
Once a widget has been defined, the widget name can be used as a command to create new objects belonging to the widget.Object usage
Once an object has been created, the object name can be used as a command to invoke methods that operate on the object.- objName method ?args...?
- Invokes a method named method on an object named objName. Remaining arguments are passed to the argument list for the method. The method name can be "constructor", "destructor", any method name appearing in the widget definition, or any of the following built-in methods.
Built-in methods
- objName cget option
- Provides access to public variables as configuration options. This mimics the behavior of the usual "cget" operation for Tk widgets. The option argument is a string of the form "-varName", and this method returns the current value of the public variable varName.
- objName configure ?option? ?value option value ...?
- Provides access to public variables as configuration options. This mimics the behavior of the usual "configure" operation for Tk widgets. With no arguments, this method returns a list of lists describing all of the public variables. Each list has three elements: the variable name, its initial value and its current value.
If a single option of the form "-varName" is specified, then this method returns the information for that one variable.
Otherwise, the arguments are treated as option/value pairs assigning new values to public variables. Each variable is assigned its new value, and if it has any "config" code associated with it, it is executed in the context of the widget where it was defined. If the "config" code generates an error, the variable is set back to its previous value, and the configure method returns an error.
- objName isa widgetName
- Returns non-zero if the given widgetName can be found in the object's heritage, and zero otherwise.
- objName info option ?args...?
- Returns information related to a particular object named objName, or to its widget definition. The option parameter includes the following things, as well as the options recognized by the usual Tcl "info" command:
- objName info widget
- Returns the name of the most-specific widget for object objName.
- objName info inherit
- Returns the list of base widgets as they were defined in the "inherit" command, or an empty string if this widget has no base widgets.
- objName info heritage
- Returns the current widget name and the entire list of base widgets in the order that they are traversed for member lookup and object destruction.
- objName info function ?cmdName? ?-protection? ?-type? ?-name? ?-args? ?-body?
- With no arguments, this command returns a list of all widgets methods and procs. If cmdName is specified, it returns information for a specific method or proc. If no flags are specified, this command returns a list with the following elements: the protection level, the type (method/proc), the qualified name, the argument list and the body. Flags can be used to request specific elements from this list.
- objName info variable ?varName? ?-protection? ?-type? ?-name? ?-init? ?-value? ?-config?
- With no arguments, this command returns a list of all object-specific variables and common data members. If varName is specified, it returns information for a specific data member. If no flags are specified, this command returns a list with the following elements: the protection level, the type (variable/common), the qualified name, the initial value, and the current value. If varName is a public variable, the "config" code is included on this list. Flags can be used to request specific elements from this list.
Chaining methods/procs
Sometimes a base widget has a method or proc that is redefined with the same name in a derived widget. This is a way of making the derived widget handle the same operations as the base widget, but with its own specialized behavior. For example, suppose we have a Toaster widget that looks like this:itcl::widget Toaster { variable crumbs 0 method toast {nslices} { if {$crumbs > 50} { error "== FIRE! FIRE! ==" } set crumbs [expr $crumbs+4*$nslices] } method clean {} { set crumbs 0 } }
We might create another widget like SmartToaster that redefines the "toast" method. If we want to access the base widget method, we can qualify it with the base widget name, to avoid ambiguity:
itcl::widget SmartToaster { inherit Toaster method toast {nslices} { if {$crumbs > 40} { clean } return [Toaster::toast $nslices] } }
Instead of hard-coding the base widget name, we can use the "chain" command like this:
itcl::widget SmartToaster { inherit Toaster method toast {nslices} { if {$crumbs > 40} { clean } return [chain $nslices] } }
The chain command searches through the widget hierarchy for a slightly more generic (base widget) implementation of a method or proc, and invokes it with the specified arguments. It starts at the current widget context and searches through base widgets in the order that they are reported by the "info heritage" command. If another implementation is not found, this command does nothing and returns the null string.
Auto-loading
Widget definitions need not be loaded explicitly; they can be loaded as needed by the usual Tcl auto-loading facility. Each directory containing widget definition files should have an accompanying "tclIndex" file. Each line in this file identifies a Tcl procedure or [incr Tcl] widget definition and the file where the definition can be found.For example, suppose a directory contains the definitions for widgets "Toaster" and "SmartToaster". Then the "tclIndex" file for this directory would look like:
# Tcl autoload index file, version 2.0 for [incr Tcl] # This file is generated by the "auto_mkindex" command # and sourced to set up indexing information for one or # more commands. Typically each line is a command that # sets an element in the auto_index array, where the # element name is the name of a command and the value is # a script that loads the command. set auto_index(::Toaster) "source $dir/Toaster.itcl" set auto_index(::SmartToaster) "source $dir/SmartToaster.itcl"
The auto_mkindex command is used to automatically generate "tclIndex" files.
The auto-loader must be made aware of this directory by appending the directory name to the "auto_path" variable. When this is in place, widgets will be auto-loaded as needed when used in an application.
C procedures
C procedures can be integrated into an [incr Tcl] widget definition to implement methods, procs, and the "config" code for public variables. Any body that starts with "@" is treated as the symbolic name for a C procedure.Symbolic names are established by registering procedures via Itcl_RegisterC(). This is usually done in the Tcl_AppInit() procedure, which is automatically called when the interpreter starts up. In the following example, the procedure My_FooCmd() is registered with the symbolic name "foo". This procedure can be referenced in the body command as "@foo".
int Tcl_AppInit(interp) Tcl_Interp *interp; /* Interpreter for application. */ { if (Itcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Itcl_RegisterC(interp, "foo", My_FooCmd) != TCL_OK) { return TCL_ERROR; } }
C procedures are implemented just like ordinary Tcl commands. See the CrtCommand man page for details. Within the procedure, widget data members can be accessed like ordinary variables using Tcl_SetVar(), Tcl_GetVar(), Tcl_TraceVar(), etc. Widget methods and procs can be executed like ordinary commands using Tcl_Eval(). [incr Tcl] makes this possible by automatically setting up the context before executing the C procedure.
This scheme provides a natural migration path for code development. Widgets can be developed quickly using Tcl code to implement the bodies. An entire application can be built and tested. When necessary, individual bodies can be implemented with C code to improve performance.
Copyright © 2008 Arnulf Wiedemann
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/ItclCmd/itclwidget.htm