package Tcl::Tk; use strict; use Tcl; use Exporter ('import'); use vars qw(@EXPORT_OK %EXPORT_TAGS); @Tcl::Tk::ISA = qw(Tcl); $Tcl::Tk::VERSION = '0.97'; sub WIDGET_CLEANUP() {0} $Tcl::Tk::DEBUG ||= 0; sub DEBUG() {0} sub Tcl::Tk::Widget::DEBUG() {0} sub _DEBUG { # Allow for optional debug level and message to be passed in. # If level is passed in, return true only if debugging is at # that level. # If message is passed in, output that message if the level # is appropriate (with any extra args passed to output). my $lvl = shift; return $Tcl::Tk::DEBUG unless defined $lvl; my $msg = shift; if (defined($msg) && ($Tcl::Tk::DEBUG >= $lvl)) { print STDERR $msg, @_; } return ($Tcl::Tk::DEBUG >= $lvl); } if (DEBUG()) { # The gestapo throws warnings whenever Perl/Tk modules are requested. # It also hijacks such requests and returns an empty module in its # place. unshift @INC, \&tk_gestapo; } =head1 NAME Tcl::Tk - Extension module for Perl giving access to Tk via the Tcl extension =head1 SYNOPSIS use Tcl::Tk; my $int = new Tcl::Tk; my $mw = $int->mainwindow; my $lab = $mw->Label(-text => "Hello world")->pack; my $btn = $mw->Button(-text => "test", -command => sub { $lab->configure(-text=>"[". $lab->cget('-text')."]"); })->pack; $int->MainLoop; Or use Tcl::Tk; my $int = new Tcl::Tk; $int->Eval(<<'EOS'); # pure-tcl code to create widgets (e.g. generated by some GUI builder) entry .e button .inc -text {increment by Perl} pack .e .inc EOS my $btn = $int->widget('.inc'); # get .inc button into play my $e = $int->widget('.e'); # get .e entry into play $e->configure(-textvariable=>\(my $var='aaa')); $btn->configure(-command=>sub{$var++}); $int->MainLoop; =head1 DESCRIPTION The C module provides access to the Tk library within Tcl/Tk installation. By using this module an interpreter object created, which then gain access to entire variety of installed Tcl libraries (Tk, Tix, BWidgets, BLT, etc) and existing features (for example natively looking widgets using C). =head2 Access to the Tcl and Tcl::Tk extensions To get access to the Tcl and Tcl::Tk extensions, put the command near the top of your program. use Tcl::Tk; =head2 Creating a Tcl interpreter for Tk Before you start using widgets, an interpreter (at least one) should be created, which will manage all things in Tcl. To create a Tcl interpreter initialised for Tk, use my $int = new Tcl::Tk; Optionally DISPLAY argument could be specified: C. This creates a Tcl interpreter object $int, and creates a main toplevel window. The window is created on display DISPLAY (defaulting to the display named in the DISPLAY environment variable) The Tcl/Tk interpreter is created automatically by the call to C and C methods, and main window object is returned in this case: use Tcl::Tk; my $mw = Tcl::Tk::MainWindow; my $int = $mw->interp; =head2 Entering the main event loop The Perl method call $int->MainLoop; on the Tcl::Tk interpreter object enters the Tk event loop. You can instead do C or CMainLoop> if you prefer. You can even do simply C if you import it from Tcl::Tk in the C statement. =head2 Creating and using widgets Two different approaches are used to manipulate widgets (or, more commonly, to manipulate any Tcl objects behaving similarly) =over =item * access with a special widget accessing syntax of kind C<< $widget->method; >> =item * random access with C<< Eval >> =back First way to manipulate widgets is identical to perl/Tk calling conventions, second one deploys Tcl syntax. Both ways are very interchangeable in that sence, a widget created with one way could be used by another way. Usually Perl programs operate with Tcl/Tk via perl/Tk syntax, so user have no need to deal with Tcl language directly, only some basic understanding of widget is needed. A possibility to use both approaches interchangeably gives an opportunity to use Tcl code created elsewhere (some WYSIWIG IDE or such). In order to get better understanding on usage of Tcl/Tk widgets from within Perl, a bit of Tcl/Tk knowledge is needed, so we'll start from 2nd approach, with Tcl's Eval (C<< $int->Eval('...') >>) and then smoothly move to 1st, approach with perl/Tk syntax. =head4 Tcl/Tk syntax =over =item * interpreter Tcl interpreter is used to process Tcl/Tk widgets; within C you create it with C, and, given any widget object, you can retreive it by C<< $widget->interp >> method. Within pure Tcl/Tk it is already exist. =item * widget path Widget path is a string starting with a dot and consisting of several names separated by dots. These names are widget names that comprise widget's hierarchy. As an example, if there exists a frame with a path C<.fram> and you want to create a button on it and name it C then you should specify name C<.fram.butt>. Widget paths are refered in miscellaneous widget operations, and geometry management is one of them. At any time widget's path could be retreived with C<< $widget->path; >> within C. =item * widget as Tcl/Tk command when widget is created, a special command is created within Tk, the name of this command is widget's path. That said, C<.fr.b> is Tk's command and this command has subcommands, those will help manipulating widget. That is why C<< $int->Eval('.fr.b configure -text {new text}'); >> makes sence. Note that C<< $button->configure(-text=>'new text'); >> does exactly that, provided a fact C<$button> corresponds to C<.fr.b> widget. =back C not only creates C package, but also it creates C package, responsible for widgets. Each widget (object blessed to C, or other widgets in ISA-relationship) behaves in such a way that its method will result in calling it's path on interpreter. =head4 Perl/Tk syntax C package within C module fully aware of perl/Tk widget syntax, which has long usage. This means that any C widget has a number of methods like C