Tcl::Tk - Extension module for Perl giving access to Tk via the Tcl extension
use Tcl; use Tcl::Tk qw(:widgets :misc); $interp = new Tcl::Tk; label(".l", -text => "Hello world"); tkpack ".l"; MainLoop;
The Tcl::Tk submodule of the Tcl module gives access to the Tk library. It does this by creating a Tcl interpreter object (using the Tcl extension) and binding in all of Tk into the interpreter (in the same way that wish or other Tcl/Tk applications do).
To get access to the Tcl and Tcl::Tk extensions, put the commands use Tcl; use Tcl::Tk;
near the top of your program. You can also import short-cut functions into your namespace from Tcl::Tk if you want to avoid using method calls for everything.
To create a Tcl interpreter initialised for Tk, use
$i = new Tcl::Tk (DISPLAY, NAME, SYNC);
All arguments are optional. This creates a Tcl interpreter object $i, and creates a main toplevel window. The window is created on display DISPLAY (defaulting to the display named in the DISPLAY environment variable) with name NAME (defaulting to the name of the Perl program, i.e. the contents of Perl variable $0). If the SYNC argument is present and true then an XSynchronize() call is done ensuring that X events are processed synchronously (and thus slowly). This is there for completeness and is only very occasionally useful for debugging errant X clients (usually at a much lower level than Tk users will want).
The Perl method call
on the Tcl::Tk interpreter object enters the Tk event loop. You can instead do
Tcl::Tk->MainLoop if you prefer. You can even do simply
MainLoop if you import it from Tcl::Tk in the
use statement. Note that commands in the Tcl and Tcl::Tk extensions closely follow the C interface names with leading Tcl_ or Tk_ removed.
If desired, widgets can be created and handled entirely by Tcl/Tk code evaluated in the Tcl interpreter object $i (created above). However, there is an additional way of creating widgets in the interpreter directly from Perl. The names of the widgets (frame, toplevel, label etc.) can be imported as direct commands from the Tcl::Tk extension. For example, if you have imported the
label command then
$l = label(".l", -text => "Hello world);
executes the command
$i->call("label", ".l", "-text", "Hello world);
and hence gets Tcl to create a new label widget .l in your Tcl/Tk interpreter. You can either import such commands one by one with, for example,
use Tcl::Tk qw(label canvas MainLoop winfo);
or you can use the pre-defined Exporter tags :widgets and :misc. The :widgets tag imports all the widget commands and the :misc tag imports all non-widget commands (see the next section).
Let's return to the creation of the label widget above. Since Tcl/Tk creates a command ".l" in the interpreter and creating a similarly named sub in Perl isn't a good idea, the Tcl::Tk extension provides a slightly more convenient way of manipulating the widget. Instead of returning the name of the new widget as a string, the above label command returns a Perl reference to the widget's name, blessed into an almost empty class. Perl method calls on the object are translated into commands for the Tcl/Tk interpreter in a very simplistic fashion. For example, the Perl command
$l->configure(-background => "green");
is translated into the command
$i->call($$l, "configure", "-background", "green");
for execution in your Tcl/Tk interpreter. Notice that it simply dereferences the object to find the widget name. There is no automagic conversion that happens: if you use a Tcl command which wants a widget pathname and you only have an object returned by
entry() or whatever) then you must dereference it yourself.
For convenience, the non-widget Tk commands (such as
winfo and so on) are also available for export as Perl commands and translate into into their Tcl equivalents for execution in your Tk/Tcl interpreter. The names of the Perl commands are the same as their Tcl equivalents except for two: Tcl's
pack command becomes
tkpack in Perl and Tcl's
bind command becomes
tkbind in Perl. The arguments you pass to any of these Perl commands are not touched by the Tcl parser: each Perl argument is passed as a separate argument to the Tcl command.
Malcolm Beattie, email@example.com