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.
Mailing lists:
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 ]:
$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.
Following example shows how Perl program can use Tcl::Tk to access Tcl/Tk. It creates and then uses pure-perl widget LabEntry2 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 # our megawidget will have two labels and two edit boxes, aligned, with # a 'frustrate' button that swaps two Entry subwidgets # 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 $lab1 = $this->Label->grid(-column=>0,-row=>0,-sticky=>'e'); my $ed1 = $this->Entry->grid(-column=>1,-row=>0,-sticky=>'w'); my $lab2 = $this->Label->grid(-column=>0,-row=>1,-sticky=>'e'); my $ed2 = $this->Entry->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); $int->my('lab1',$lab1->path); $int->my('ed1',$ed1->path); $int->my('lab2',$lab2->path); $int->my('ed2',$ed2->path); }, 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 for ($this->children) { print STDERR "\@\@"; $_->destroy; } }); # 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 $int->_gridForget($int->my('ed1'),$int->my('ed2')); $int->_grid($int->my('ed1'),qw/-column 1 -row 1 -sticky w/); $int->_grid($int->my('ed2'),qw/-column 1 -row 0 -sticky w/); }); # ... options $int->metawidgetOption('LabEntry2', '-lab1', sub { my (undef,$int,undef,$aa) = @_; $int->my('-lab1',$aa); $int->widget($int->my('lab1'))->configure(-text=>$aa); }); $int->metawidgetOption('LabEntry2', '-lab2', sub { my (undef,$int,undef,$aa) = @_; $int->my('-lab2',$aa); $int->widget($int->my('lab2'))->configure(-text=>$aa); }); $int->metawidgetOption('LabEntry2', '-textvariable1', sub { my (undef,$int,undef,$aa) = @_; $int->widget($int->my('ed1'))->configure(-textvariable=>$aa); }); $int->metawidgetOption('LabEntry2', '-textvariable2', sub { my (undef,$int,undef,$aa) = @_; $int->widget($int->my('ed2'))->configure(-textvariable=>$aa); }); # 3. now Tcl/Tk has our megawidget; bring it to Perl $mw->Declare('LabEntry2','labentry2'); # megawidget creation completed. now use it my ($v1,$v2,$v3) = qw(one two three); my $mywid = $mw->LabEntry2(-lab1=>'l1',-lab2=>'l2',-textvariable1=>\$v1,-textvariable2=>\$v2)->pack; my $mywid1 = $mw->LabEntry2(-lab1=>'XXX',-lab2=>'O',-textvariable1=>\$v1,-textvariable2=>\$v3)->pack; # I wonder what is 2nd label of 2nd widget? print STDERR "2nd label of 2nd widget is ",$mywid1->cget('-lab2'),"\n"; $mw->Scrolled('Text')->pack(-fill=>'both',-expand=>1)->_insertEnd("".$int->_infoBody('tclPkgUnknown')); $int->MainLoop;
Pure-perl widgets based on other Tcl approaches will be also added.
RLH - Since both are PM modules can I just drop them in my lib path (on Windows XP) and be off and running?
VK - Tcl::Tk is pure perl, but Tcl module is not (has XS). Tcl/Tk itself could be used ActiveState. BTW Perl module with a name Tcl is trivial to compile. Ask Tcl::Tk user's mailing list.