With vanilla Tcl/Tk, the widget access command is the same as the window name. If you create a button named ".b", then you use the command ".b" to access it.
With namespaces, this is not necessarily true. If a widget is created within a namespace, then its access command is protected by the namespace. Within the namespace, the access command is indeed the same as the window name. Outside of the namespace, however, you should use the complete namespace path to access the widget:
namespace foo {
label .x -text "X"
.x configure -background red
}
foo::.x configure -relief raised
You can still use the window name ".x" as an argument to other Tk commands, regardless of the namespace context:
namespace foo {
set w [winfo width .x]
}
set w [winfo width .x]
pack .x
destroy .x
The namespace qualifiers are only needed in conjunction with the widget access command, which is always the first word on a command line.
Many existing Tk applications assume that the window name can be used as the access command. If the usual namespace rules described above were strictly enforced, many existing applications would break. For this reason, there is a "backward compatibility" mode in [incr Tcl] that makes the distinction between the window name and the access command much less of a problem. If an unknown command is recognized as a Tk widget, the unknown procedure automatically uses winfo command to find the access command for the widget. With the "backward compatibility" mode, the following code still works:
namespace foo {
label .x -text "X"
.x configure -background red
}
.x configure -relief raised
Although this works, execution is a little slower. In general, the following guidelines should be followed when using widgets within namespaces:
- When a widget is created within a namespace, it is a signal that the widget is meant to be protected by the namespace. The widget should not be accessed directly outside of the namespace.
- In bindings, the %q field should be used instead of %W as the widget access access command.
If a widget is meant to be generally available, it should be created in the global namespace. This can be accomplished from within a namespace like this:
namespace foo {
uplevel #0 button .b -text "Push Me"
}
or like this:
namespace foo {
button .b -text "Push Me"
rename .b ::.b
}
Library procedures can be written to operate on any window using the winfo command query.