- for users is 'tcltk' hosted by perl.org, to subscribe write to [email protected]
- for developers is tcltk-perl hosted by lists.sourceforge.net, subscription is at http://lists.sourceforge.net/lists/listinfo/tcltk-perl
- 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, BWidget, Tix, tile, iwidgets, VUW Widgets, 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). Perl module with a name Tcl is trivial to compile. Look /ask for/... in Tcl::Tk wiki for binaries.
Examples edit
by XyemBuilding Tcl for Tcl 8.5:The Tcl module ( 0.97 ) tries to use stubs for Tcl 8.4 which results in a segmentation error when the Tcl module is used in Perl, despite passing all tests. To create the Makefile for building it for Tcl 8.5 on my Ubuntu ( 8.04 ) machine I used:perl Makefile.PL --nousestubs --library=-ltcl8.5 --include=-I/usr/include/tcl8.5/JH: It should not be necessary to do that if you built properly with 8.4 stubs and not the regular library. Stubs ensures the upwards compatibility to 8.4+. The above line will create an 8.5-only version which won't work with 8.6.Xyem 2008-10-08 09:28 UTC: When I try to build Tcl 0.97 downloaded from CPAN "normally", the following transpires:
xyem@puppy:~$ tar zxvf Tcl-0.97.tar.gz ( ..snip.. ) xyem@puppy:~$ cd Tcl-0.97/ xyem@puppy:~/Tcl-0.97$ mkdir -p /tmp/perl/lib xyem@puppy:~/Tcl-0.97$ perl Makefile.PL PREFIX=~/tmp/perl LIB=~/tmp/perl/lib LIBS = -Ltcl-core/linux-i686 -ltclstub8.4 INC = -Itcl-core/include DEFINE = -DUSE_TCL_STUBS Checking if your kit is complete... Looks good Warning: -Ltcl-core/linux-i686 changed to -L/home/xyem/Tcl-0.97/tcl-core/linux-i686 Writing Makefile for Tcl xyem@puppy:~/Tcl-0.97$ make ( ..snip.. compiles fine ) xyem@puppy:~/Tcl-0.97$ make test PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t ( ..snip.. all tests pass, none skipped ) All tests successful. Files=10, Tests=53, 2 wallclock secs ( 0.78 cusr + 0.14 csys = 0.92 CPU) xyem@puppy:~/Tcl-0.97$ make install ( ..snip.. ) xyem@puppy:~/Tcl-0.97$ export PERL5LIB=~/tmp/perl/lib xyem@puppy:~/Tcl-0.97$ perl -MTcl Segmentation fault xyem@puppy:~/Tcl-0.97$JH: I find the above results odd ... the make test works correctly, but not the installed use case? Are you sure that the same Tcl and Perl and referenced in each case?Xyem 2008-10-12 22:40 UTC: Freshly installed Ubuntu 8.04 gives this behaviour, so there is only one Tcl and Perl installed. Running Tcl alone ( tclsh ) works fine, as does building it specifically for 8.5. I would do more research into it but I don't know where to start. I do recall while Googling the issue that I was not alone.. I can put up a virtual machine and give you ssh access if you are interested in looking into it?Xyem 2009-04-20 09:51 UTC: I tried to "do it properly" as root, seeing if my cpan configuration was causing issues. It does exactly the same thing.Tcl lists returned as string instead of an array (workaround)Tcl::Tk has a list of methods that returns lists as part of the module which, it seems, you cannot modify without editing the module source. The list is not exhaustive and fails to Do What You Expect when using certain widgets ( mainly non-core ones like BWidgets ).
my @Nodes = $BWidget_Tree -> nodes ( 'root' ); # @Nodes contains only a single element, a string of node indices, "1 2 3 4 5"One workaround is to not use the Widgets method, but make the call more directly.
my @Nodes = $Tcl -> call ( $BWidget_Tree, 'nodes', 'root' ); # @Nodes contains node indices, ( 1, 2, 3, 4, 5 )Doing it this way instead should prevent code that would normally split the ( erroneously? ) returned string from breaking if the method gets added to the returns-a-list list in Tcl::Tk in the future.JH: The BWidget tree nodes call in Tcl is returning something of proper list type, so we would have to trace where the list type is lost in translation.Xyem 2008-10-12 22:40 UTC: Don't know how but I am more than happy and willing to learn :)