Version 1 of Tcl::Tk

Updated 2005-02-02 14:43:41

Tcl::Tk is an alternative binding to Tcl/Tk from Perl (as opposed to Perl/Tk). It uses Tcl in the bridge (which Perl/Tk does not). These are the Tcl [L1 ] and Tcl::Tk [L2 ] modules for Perl. Make sure you get the latest.

It has advantages over the traditional Perl/Tk in using less memory and being faster, as well as being more portable and flexible (for example, for use on Windows/CE). It gains this by linking directly against Tcl using a bridge that has deep understanding of Tcl_Objs and PerlSVs. It has a slightly varied interface, but there is a rough Perl/Tk compatability layer (about 80% compatability). It would be nice to see another module layered on top that provides near 100% Perl/Tk compability while maintaining the efficient lower layer that ties tightly to Tcl.

VK: Other advantages of Tcl, Tcl::Tk perl modules over Perl/Tk are briefly listed at perl's discussion site [L3 ]:

  • Perl<->Tcl/Tk bridge is lightweight, any misbehaviour is hidden is 70Kb of pure-perl Tcl::Tk code and 30Kb of Tcl bridge code; perlTk is huge and really hard to maintain. It took really many efforts to switch to Unicode between versions Tk800.024 <->Tk804.027
  • Most up-to-date Tcl/Tk could easily be used. Tcl-8.5 is really soon to come, and I already tried it from Perl.
  • You can use Unicode GUI in Perl version 5.6.x, and perlTk lacks support for Unicode for 5.6.x.
  • You have a much richier set of widgets, plus pure-Tcl widgets, and the many widget extensions developed for Tcl/Tk.
  • It is the only way to have Perl+Tk GUI on WinCE devices. PerlTk is harder to port to another platform, and perlTk Unicode version is not ported to WinCE (only elder one).
  • True native OS X (Aqua) Tk is usable.
  • As a general rule, it is easier to maintain structured things. That said, Perl does its own evolving, and Tcl/Tk does its own. Contrary, perlTk contains "Tk" and "Tix" mixed in it, and you do not know how old they are, plus some pure-Perl widgets that do not have Tcl/Tk counterpart, and perlTk documentation contains a lot of documentation rudiments that fixed in Tcl/Tk
  • Perl motto "TIMTOWTDI" is wider: you can do
 $interpreter->Eval('pure-tcl-code-to-create-and-manipulate-widgets');

or use perlTk syntax

 my $btn=$frame->Button(-text=>'Ok',-command=>sub{print 'ok'})->pack;

Disadvantage and major compat issue over Perl/Tk is lack of documented way for creating of pure-perl widgets. This is currently work in progress. It is all technically possible, just needs to be done. Since Tcl::Tk is open to the world of Tcl/Tk widget sets (BLT, BWidgets, Tix, tile, iwidgets, vu, Tktable, ...), developers of new (from scratch) apps may find it easier to use these, but compat for older apps should remain a consideration.

an example of pure-perl widget based on mkWidgets package:

 use Tcl::Tk;

 my $int = new Tcl::Tk;
 my $mw = $int->mainwindow;

 #
 # make pure-perl widget
 #
 # 1. bring mkWidgets package, it provides megawidgets (among others are snit, Tix, BWidget, IWidgets)
 $int->pkg_require('mkWidgets');
 # 2. create metawidget
 # 2.1 metawidget itself
 $int->metawidgetCreate('LabEntry2', sub {
         #print STDERR "init proc: instantiation of a metawidget; create internal widgets\n";
         my $this = $int->widget($int->GetVar('this'));
         my ($var1,$var2);
         my ($rvar1,$rvar2) = \($var1,$var2);
         my $lab1 = $this->Label(-text=>'lab1')->grid(-column=>0,-row=>0,-sticky=>'e');
         my $ed1 = $this->Entry(-textvariable=>\$var1)->grid(-column=>1,-row=>0,-sticky=>'w');
         my $lab2 = $this->Label(-text=>'lab2      [][][]')->grid(-column=>0,-row=>1,-sticky=>'e');
         my $ed2 = $this->Entry(-textvariable=>\$var2)->grid(-column=>1,-row=>1,-sticky=>'w');
         my $btn = $this->Button(-text=>'frustrate',-command=>sub{$this->frustrate})
             ->grid(-column=>0,-row=>2,-sticky=>'we',-columnspan=>2);
         $this->widget_data->{w} = [$lab1,$ed1,$lab2,$ed2,$btn,$rvar1,$rvar2];
     }, sub {
         print STDERR "exit proc: destruction of a metawidget; delete internal widgets\n";
         my $this = $int->widget($int->GetVar('this'));
         # do I need deleting child widgets? those are deleted automatically
     });
 # 2.2 some of its methods/options
 $int->metawidgetCommand('LabEntry2', frustrate=> sub {
         my $this = $int->widget($int->GetVar('this'));
         # frustrate method of our megawidget swaps two entry subwidgets, so user will be frustrated
         # TODO
         print STDERR "frustrate\n";
     });
 $int->metawidgetOption('LabEntry2', -textvariable1=> sub {
         my $this = $int->widget($int->GetVar('this'));
         # TODO
         print STDERR "frustrate\n";
     });

 # 3. now Tcl/Tk has our megawidget; bring it to Perl
 $mw->Declare('LabEntry2','labentry2');

 # megawidget creation completed. now use it
 my $mywid = $mw->LabEntry2->pack;

 $int->MainLoop;

Code above will be cleaned up and commented later, and also demonstrations of pure-perl widgets based on other Tcl approaches will be added.