
Copyright (c) 1995-1996 Nick Ing-Simmons. All rights reserved. This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself, with the exception of the files in the pTk sub-directory which have separate terms derived from those of the orignal Tk4.0 sources and/or Tix. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. See pTk/license.terms for details of this Tk license, and pTk/Tix.license for the Tix license.
This compilation of Frequently Asked Questions & answers (FAQ) is intended to answer several of the first (and largely more basic) questions posted to the comp.lang.perl.tk newsgroup and the ptk mailing list.
This document concerns itself with the Perl/Tk programming language (or, if you prefer, the Tk extension to Perl). Please be aware that this is not the Perl FAQ, this is not the Tcl FAQ, nor is this the Tcl/Tk FAQ. Each of those other documents is a useful source of information for Perl/Tk programmers but they are completely different from this one.
This is a dynamic document and contributions, clarifications, and corrections are most welcome! Please send e-mail to <pvhp@lns62.lns.cornell.edu> or to <pvhp@forte.com>. With your help this document will get better (-:
Return to table of contents
Perl/Tk (also known as pTk or ptk) is a collection of modules and code
that attempts to wed the easily configured Tk 4 widget toolkit to the
powerful lexigraphic, dynamic memory, I/O, and object-oriented capabilities
of Perl 5. In other words, it is an interpreted scripting language for
making widgets and programs with Graphical User Interfaces (GUI).
(Examples of widget programs [not necessarily written in perl/Tk]
include xterm, xclock, most web-browsers,
etc.. They are programs with "GUI" interfaces of one
sort or another and are subject to the effects of your window manager.)
The current release of Perl/Tk is based on "Tk 4.0p3" the widget Toolkit originally associated with the Tcl (Tool command language) scripting language. However, Perl/Tk does not require any of the lexical features/idiosynchrocies of Tcl. Perl/Tk uses perl 5 syntax, grammar, and data structures.
The ``Tk400.202'' package is the production release of perl/Tk (corresponding to Tcl/Tk-4.0p3) and was written primarily by Nick Ing-Simmons <Nick.Ing-Simmons@tiuk.ti.com> at Texas Instruments in Northampton, England, to work with the latest version of Larry Wall's ``perl''. Nick Ing-Simmons is currently busy converting the Tcl/Tk-4.1 code to perl callable code as well. An initial alpha release of the effort is available from CPAN as ``Tk402.000''.
The pTk code proper is an externally callable Tk toolkit (i.e. a re-write of the Tk 4.0 code that allows easier external linking & calling, especially by perl). Ptk can then be called from Perl 5 via the Tk.pm et al perl glue modules. Hence "ptk" does not necessarily refer to Perl Tk but could be taken to mean portable Tk - given a glue package to another language. The stated goal of the pTk code is to have its library usable from perl, Tcl, LISP, C++, python, etc.. It just so happens that present work is concentrating on perl.
Historical note: "ptk" was known as "ntk" before about 11:30 EST 4 May 1995.
The perl/Tk language is itself further extensible via the standard perl 5 module mechanism. A number of composite widget and special character extensions to the language have been written using perl modules.
Return to table of contents
2. What is the difference between perl/Tk and Tkperl?
TkPerl was originally the name of a (now unsupported) perl 4 package that Malcolm Beattie <mbeattie@sable.ox.ac.uk> at Oxford University gave to his code to wed the Tk X toolkit with Perl. (He has since referred to that package as a different "kettle of fish" from perl/Tk.)
Since that beginning Malcolm has also come up with a Tcl module for perl 5 that has a Tcl::Tk module extension. That module allows the use of Tcl within a Perl script (i.e. you must know both languages to get your widgets to work.) If you are interested in that package instead, see the necessary kits for Malcolm Beattie's Tcl/Tk extensions to Perl, which have been distrubuted as Tcl-b#.tar.gz and TclTk-b#.tar.gz files in the authors/id/MICB/ directory at CPAN sites (locations given in a separate question in this FAQ).
The name "tkperl" is sometimes applied to the "perl/Tk" or "ptk" package that is the subject of this FAQ. Nick Ing-Simmons prefers "perl/Tk" as the name of the package, with "pTk" or "ptk" as contractions of that name as well as referring to something technically distinct: given the extensibility of the pTk code the "p" could also be taken to mean 'portable' or 'pure' (not to be confused with either the Helsinki University of Technology portTk, nor with Brian Warkentine's Rivet). In this document the code of interest is either referred to as "perl/Tk", "pTk", or "ptk" though the primary focus is on perl/Tk.
Warning: do not attempt to install both perl/Tk and Tcl/Tkperl in the same perl installation. The names in the respective modules overlap. In particular the Tcl::Tk module is declared in a Tk.pm file - so a statement like:
use Tk;
will probably confuse your perl. If you cannot live without either module
then install make & maintain separate perls for each and arrange your
script writing accordingly (this will not be easy).
A more extensive comparison of the differences between the Tkperl and the perl/Tk code is given in the Tcl-perl.pod file that is distributed with perl/Tk (see the following questions for locations).
Lastly, it should be mentioned that if you build your perl/Tk statically rather than dynamically it will make a new perl interpreter called tkperl (confusing isn't it? :-).
Return to table of contents
3. Do I need Tcl/Tk in order to build Perl/Tk?
Short answer: No not at all. Perl/Tk is completely independent of Tcl/Tk.
Longer answer: In order to build Perl/Tk from source code you do need a recent version of perl, the perl/Tk source code kit, a graphical user interface library such as Xlib, a C or C++ compiler, and a make utility. In some rare cases Perl/Tk binaries are distributed for some platforms but that is more the exception than a general rule (see below).
If you will be attempting to port Perl/Tk to your platfrom then you might want to consult the document at:
http://w4.lns.cornell.edu/~pvhp/ptk/ptkPORT.html
where each of these necessities is discussed in a bit more detail.
Return to table of contents
(The rest of this question remains for historical reasons, as well as to point out some non CPAN resources.)
Tk-b8: The Tk-b8 kit remains on CPAN since it was compatible with the widely distributed and installed Perl (5.001m)
Australia (please be patient and only try during off hours)
ftp://syd.dit.csiro.au/pub/perl5/local/perl5.001m+Tk-b8-Linux-ELF.tar.gz
It unpacks into /usr/local. You need to have ELF running and to
have the ELF X11 libraries (please be patient and only try during
off hours).
Binaries for the old Perl 5 & Tk-b6 are available for a number of UNIX platforms courtesy of Thomas Schlagel and Alan Stange of Brookhaven Lab at:
USA
http://pubweb.bnl.gov/~ptk/
Thomas and Alan have recently (winter 1995-1996) announced that they will
update the Tk module version number of the many binaries they distribute.
Return to table of contents
"CPAN" = Comprehensive Perl Archive Network a worldwide collection of anonymous ftp sites for Perl et al (not to be confused with CTAN which is for TeX, nor CSPAN which rarely deals with computer software). The files of particular interest to a perl/Tk programmer would include:
Updated: Sun Dec 8 17:12:55 EST 1996
Africa
South Africa
ftp://ftp.is.co.za/programming/perl/CPAN/ 196.4.160.12
Asia
Hong Kong
ftp://ftp.hkstar.com/pub/CPAN/ 202.82.7.4
Japan
ftp://ftp.jaist.ac.jp/pub/lang/perl/CPAN/ 150.65.7.5
ftp://ftp.lab.kdd.co.jp/lang/perl/CPAN/ 192.26.91.6
South Korea
ftp://ftp.nuri.net/pub/CPAN/ 203.255.112.6
Taiwan
ftp://dongpo.math.ncu.edu.tw/perl/CPAN/ 140.115.25.3
Australasia
Australia
ftp://coombs.anu.edu.au/pub/perl/CPAN/ 150.203.76.2
ftp://ftp.mame.mu.oz.au/pub/perl/CPAN/ 128.250.209.2
New Zealand
ftp://ftp.tekotago.ac.nz/pub/perl/CPAN/ 202.49.6.24
Europe
Austria
ftp://ftp.tuwien.ac.at/pub/languages/perl/CPAN/ 128.130.34.160
Belgium
ftp://ftp.kulnet.kuleuven.ac.be/pub/mirror/CPAN/ 134.58.127.2
Czech Republic
ftp://sunsite.mff.cuni.cz/Languages/Perl/CPAN/ 194.50.23.220
Denmark
ftp://sunsite.auc.dk/pub/languages/perl/CPAN/ 130.225.51.30
Finland
ftp://ftp.funet.fi/pub/languages/perl/CPAN/ 128.214.248.6
France
ftp://ftp.pasteur.fr/pub/computing/unix/perl/CPAN/ 157.99.64.12
Germany
ftp://ftp.leo.org/pub/comp/programming/languages/perl/CPAN/ 131.159.0.252
ftp://ftp.rz.ruhr-uni-bochum.de/pub/CPAN/ 134.147.32.42
ftp://ftp.uni-hamburg.de/pub/soft/lang/perl/CPAN/ 134.100.32.54
Greece
ftp://ftp.ntua.gr/pub/lang/perl/
Hungary
ftp://ftp.kfki.hu/pub/packages/perl/CPAN/ 148.6.0.5
Italy
ftp://cis.utovrm.it/CPAN/ 160.80.22.17
the Netherlands
ftp://ftp.cs.ruu.nl/pub/PERL/CPAN/ 131.211.80.17
ftp://ftp.EU.net/packages/cpan/ 134.222.91.7
Norway
ftp://ftp.uit.no/pub/languages/perl/cpan/ 129.242.4.34
Poland
ftp://ftp.pk.edu.pl/pub/lang/perl/CPAN/ 149.156.132.152
ftp://sunsite.icm.edu.pl/pub/CPAN/ 148.81.209.3
Portugal
ftp://ftp.ci.uminho.pt/pub/lang/perl/ 193.136.16.247
ftp://ftp.telepac.pt/pub/CPAN/ 194.65.5.98
Russia
ftp://ftp.sai.msu.su/pub/lang/perl/CPAN/ 158.250.29.1
Slovenia
ftp://ftp.arnes.si/software/perl/CPAN/ 193.2.1.72
Spain
ftp://ftp.etse.urv.es/pub/mirror/perl/ 193.144.20.6
ftp://ftp.rediris.es/mirror/CPAN/ 130.206.1.2
Sweden
ftp://ftp.sunet.se/pub/lang/perl/CPAN/ 130.238.253.4
Switzerland
ftp://sunsite.cnlab-switch.ch/mirror/CPAN/ 193.5.24.1
UK
ftp://ftp.demon.co.uk/pub/mirrors/perl/CPAN/ 158.152.1.44
ftp://sunsite.doc.ic.ac.uk/packages/CPAN/ 193.63.255.1
ftp://unix.hensa.ac.uk/mirrors/perl-CPAN/ 129.12.200.129
North America
Ontario
ftp://ftp.utilis.com/public/CPAN/ 207.34.209.49
ftp://enterprise.ic.gc.ca/pub/perl/CPAN/ 192.197.182.100
California
ftp://ftp.digital.com/pub/plan/perl/CPAN/ 204.123.2.4
ftp://ftp.cdrom.com/pub/perl/CPAN/ 165.113.58.253
Colorado
ftp://ftp.cs.colorado.edu/pub/perl/CPAN/ 128.138.243.20
Florida
ftp://ftp.cis.ufl.edu/pub/perl/CPAN/ 128.227.205.206
Illinois
ftp://uiarchive.cso.uiuc.edu/pub/lang/perl/CPAN/ 128.174.5.14
Massachusetts
ftp://ftp.iguide.com/pub/mirrors/packages/perl/CPAN/ 206.15.105.99
New York
ftp://ftp.rge.com/pub/languages/perl/ 157.225.178.12
North Carolina
ftp://ftp.duke.edu/pub/perl/ 152.3.233.7
Oklahoma
ftp://ftp.ou.edu/mirrors/CPAN/ 129.15.2.40
Oregon
ftp://ftp.orst.edu/pub/packages/CPAN/ 128.193.4.12
Texas
ftp://ftp.sedl.org/pub/mirrors/CPAN/ 198.213.9.194
ftp://ftp.metronet.com/pub/perl/ 192.245.137.6
South America
Chile
ftp://sunsite.dcc.uchile.cl/pub/Lang/perl/CPAN/ 146.83.5.204
For those equipped with multi-protocol browsers you might pay a visit to
Tom Christiansen's CPAN
multiplexer
whose relevant Tk URLs are (the second one is not active since it violates the
HTML-2.0 spec according to nsgmls):
http://perl.com/cgi-bin/cpan_mod?module=Tk
http://perl.com/cgi-bin/cpan_mod?module=Tk&readme=1
According to Stephen P. Potter some of the CPAN sites have decompression on the
fly for people who do not have programs like gunzip. For example,
at the ufl site (Florida USA) type this into your ftp session to download a
gunzipped version of Tk:
ftp> get Tk400.202.tar.gz Tk400.202.tar
If you have the appropriate CPAN and FTP modules (yes there is a CPAN module
for retreiving CPAN modules and its name is CPAN oddly enough) already
installed you can
retrieve a module from CPAN and carry out a complete
installation with a perl one-liner like this:
perl -MCPAN -e 'install "Tk"'
For more information on CPAN you can send e-mail to the CPAN administrators,
<cpan-adm@ftp.funet.fi>.
If you know of some Perl resources that seem not to be in the CPAN
(you did check the contents listings in indices/, didn't you?) please tell
the CPAN administrators.
If you have some modules/scripts/documentation yourself that you
would like to contribute to CPAN, please read the file authors/00upload.howto
and let the CPAN administrators know about it.
Return to table of contents
In general, building perl/Tk requires:
cc
compilers, as well as with the free GNU gcc compiler. A
make utility of some sort (make/gmake)
will be extremely helpful.
Step - by - step the commands to build the Tk extension to Perl are (for the dynamically linked version) roughly as follows:
Note carefully that this process leaves behind a large amount of documentation and examples in various sub-directories. You are strongly encouraged to look carefully through your build tree for docs, examples, etc. and keep those valuable files in a safe place. You might consider tar-ing them off and installing in a webserver directory tree.
A relatively easy way to determine if the perl on your system allows for dynamic linking was mentioned by Kenneth Albanowski <kjahds@kjahds.com>. If the following does not say "dl_none.xs" then you probably do have dynamically linked perl (or perhaps a very non-Unixy perl):
perl -e 'use Config; print $Config{dlsrc},"\n"'
(thanks to Paul Lussier <plussier@isd.3com.com> for the correction!).
Here is a little more detailed discussion of each the steps just given:
perl Makefile.PL X11=/usr/local/X11R5
or perhaps different directory tree specification is necessary with your X
installation:
perl Makefile.PL X11INC=/usr/local/share/X11R5/include \
X11LIB=/usr/local/arch/X11R5/lib
There are system and site dependencies in all of the above steps.
However, the largest single source of build trouble comes from not using the
latest versions of the various utilities (C compiler,
make, etc.). In particular ensure that when you say
perl Makefile.PL that the perl that gets invoked is up to
date - use
which perl (or whence perl)
and perl -v to determine this. If
necessary specify the full path name to your perl5 interpreter/compiler.
(Some people do not rm their older perl interpreters
when upgrading to a more recent version - beware.)
If you still run into trouble take a look at the INSTALL, the README and the README file for your specific system (e.g. README.AIX, README.OSF, etc.). You might also find your system mentioned in the ptk hyper-mail archive at:
http://www.rosat.mpe-garching.mpg.de/mailing-lists/ptk/
or
http://pubweb.bnl.gov/~ptk/
or
ftp://ftp.ccd.bnl.gov/pub/ptk/archives/
or the Perl 5 Porters page at one of the following URLs:
http://www.rosat.mpe-garching.mpg.de/mailing-lists/Perl5-Porters/
http://www.hut.fi/~jhi/perl5-porters.html
If you wish to discuss your Tk build problems with others run and save the
output from the myConfig script in the Tk build directory
(the output may already be in the myConfig.out file from your
perl/Tk build directory), as well as the myconfig script in your
perl build directory (or the output of perl -V with a capitol V).
It is often helpful to include the output of either
(or both) of these scripts in your discussion.
Presented here are the beginnings of a list of problems associated with building perl/Tk on various platforms (for help building perl itself please refer to the Perl FAQ). This list is in no way complete nor authoritative (nor is it necessarily even up-to-date!) but simply lists problems people have reported. Keep in mind that your installation may differ (e.g. location differences such as /usr/bin/perl vs. /usr/local/bin/perl) even if its the same platform listed here:
For Tk-b8: modifying the perl.exp file may be necessary. There is a patch in Tk-b8/README.AIX. It may be necessary to make regen_headers after the patch.
Previous versions: Most people seem to prefer the dynamic linking afforded by a recent version of the gcc compiler on this system.
MachTen's pwd.h can't be included more that once or you get an error.
It looked to me like tclUnix.h was only used in tclUnixUtil.c, so I commented out the #include <pwd.h> in tclUnix.h.
For Tk-b8: make is reputedly not up to the task on this system.
Tk-b8/README.OSF recommends gmake instead.
Stephane Bortzmeyer
<bortzmeyer@pasteur.fr>
reports a successful build with Perl 5.001m, xsubpp 1.922,
MakeMaker 4.23. He points out that it was necessary for him to
upgrade the xsubpp and MakeMaker that he received with his copy of
Perl5.001m.
Matthew Black <black@csulb.edu> recently mentioned a need to apply "patchSG0000596" to get perl sockets to work. His message was copyrighted and is not included here. Send e-mail to him to find out where the get "patchSG0000596".
John Stoffel reports a successful build of static Tk-b10 on Ultrix 4.5.
http://www.rosat.mpe-garching.mpg.de/mailing-lists/Perl5-Porters/
http://www.hut.fi/~jhi/perl5-porters.html
In general your non-Unix platform must be able to support perl 5 and
Xlib
(a C compiler and a make utility are tremendously useful too).
If you want to run perl/Tk on another computer and simply have the display show
up on yours then all you need on your computer is an "X server"
The long list of UNIX and non-unix
perl 5 ports, Tcl/Tk ports, and Perl/Tk ports that used to
appear in this FAQ has now moved to a separate web page at:
http://w4.lns.cornell.edu/~pvhp/ptk/ptkPORT.html
Return to table of contents
7. Where is the Documentation?
A great deal of Perl/Tk documentation gets installed as part of the Tk extension building process. Hence, a great deal of documentation is probably residing on your computer already.
More documentation is "in the works": there are several books dealing with perl/Tk in progress, an ongoing magazine column and a growing FAQ (the document you are presently reading).
The additional material you may want to look at can be split into Perl/Tk, Perl, Tcl/Tk, and X documentation categories:
In your Tk build directory there should be a doc/ sub-directory in which there are a number of .htm files (after you make install). These files were originally Tcl/Tk man pages (from the man* sub-directories), but the *.htm files have been converted to Perl syntax and rendered in HTML format. You can use the Perl/Tk web browser to view them locally with a command like:
tkweb index.html
or you may view them on the web itself by installing them in a web-server
directory tree, or by pointing a browser at:
http://w4.lns.cornell.edu/~pvhp/ptk/doc/
The nTk/pTk Mailing List Archive is a very useful source of information too, and is accesible at either
http://pubweb.bnl.gov/~ptk/
or via ftp at
ftp://ftp.ccd.bnl.gov/pub/ptk/archives/
(both in the USA). You may search the contents of another ptk mailing
list hypertext archive thanks to a cgi-bin script written by Achim Bohnet in
Germany at:
http://www.rosat.mpe-garching.mpg.de/mailing-lists/ptk/
You must subscribe to the mailing list to receive e-mail from the list.
To subscribe to the mailing list you can send mail to
majordomo@lists.stanford.edu
(i.e.
<majordomo@lists.stanford.edu>)
with the following command in the body of your e-mail message:
subscribe ptk joe.user@somewhere (Joe D. User)
To send a message to all recipients of the mailing list send e-mail to <ptk@lists.stanford.edu>.
To remove yourself from the mailing list send e-mail to majordomo@lists.stanford.edu (i.e. <majordomo@lists.stanford.edu>) with the following command in the body of your e-mail message:
unsubscribe ptk joe.user@somewhere (Joe D. User)
Where instead of "joe.user@somewhere" you might very well like to substitute
another string of characters.
(Please note: one does not send unsubscribe messages to the ptk list. One does send "unsubscribe ptk" messages to a special e-mail list administration program. In the case of the ptk list you send to majordomo@lists.stanford.edu. You must of course do this from the account and computer from which you initially subscribed. In particular if you are viewing the hypertext version of this FAQ you may not be able to unsubscribe from majordomo@lists.stanford.edu by following the mailto: hyperlinks - if your web-browser account/computer is different from your subscribe to e-mail-lists account/computer (the details of this might depend on which browser you use though). Thank you for your cooperation on this.)
In order to determine where on your system the perl5/ directory is located type the following one-line perl command (at your shell prompt - this is not a line from a perl script):
perl -e 'print join("\n",@INC,"");'
If that command does not turn up a perl5/ directory then
make sure that you are running perl 5 with the following: perl -v
(this too can simply be entered at the shell prompt).
The raw pod files that come with the Tk kit are examples of the perl
"plain old documentation" format and are just about human
readable as they are (e.g. you may more,
cat, or less them; or send them to a printer).
Many (not all) of the perl/Tk pod documents get are
converted to *roff format and are installed in you perl man page area as part
of the perl/Tk build process.
If you have a recent version of perl/Tk try something like man 3 Tk::Tk. If this does not work check your manual page path with
perl -MConfig -e 'print $Config{man1dir},"\n",$Config{man3dir},"\n"'
And if you still cannot find the manual pages check with your system
administrator for the proper MANPATH and/or Tk installation version.
"Raw" .pod (such as UserGuide.pod) can be viewed with the tkpod hypertext pod viewer. Raw .pod may also be run through any one or more of a large numbers of re-formatting perl filters. Such programs include pod2man, pod2text, pod2html, pod2latex, etc. (these get installed when you install perl). Other translators pod2texinfo, pod2fm, pod2pdf, etc., also exist. Check a CPAN site for these scripts if you do not already have them.
A command line like the following (but subject to local variations) should work for you:
tkpod site_perl/Tk/UserGuide.pod
or if you like Unix manual page style:
pod2man perl5/Tk/UserGuide.pod | nroff -man | more
(note that I am showing examples with almost full file path names - the
alternative would be to cd into the appropriate directory then type:
pod2man UserGuide.pod | nroff -man | more
There should even be a perl script to run that above command for you. It is
executed as:
perldoc UserGuide
Note that if there is pod like documentation in a perl module you
may also execute tkpod (or perldoc) on it as in:
tkpod ColorEditor.pm
(please note that unfortunately, not all .pm mod files
have pod
embedded.)
If you have misplaced your tkpod program but still want that GUI look and feel (like xman) make the appropriate changes to the following script:
#!/usr/bin/perl
use Tk;
use Tk::Pod;
my $m = new MainWindow;
$m -> Pod(-file => 'ColorEditor.pm');
# or use command line path/filename:
# $m -> Pod(-file => $ARGV[0]);
MainLoop;
World Wide Web - perl/Tk man pages
http://pubweb.bnl.gov/~ptk/doc/index.html
http://w4.lns.cornell.edu/~pvhp/ptk/doc/
http://w4.lns.cornell.edu/~pvhp/ptk/pod/
The Perl/Tk Newsgroup
comp.lang.perl.tk
Perl Newsgroups
comp.lang.perl.misc
comp.lang.perl.anounce
comp.lang.perl.modules
Tcl Newsgroups
comp.lang.tcl
comp.lang.tcl.announce
Miscellaneous Newsgroups
comp.answers
news.answers
Perl/Tk FAQ-Archives (ftp sites) [Note: FAQ may be many separate files]
(see also CPAN sites)
ftp://rtfm.mit.edu/pub/usenet/comp.lang.perl.tk
ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/comp/lang/perl/tk
ftp://ftp.uu.net/usenet/news.answers/perl-faq/ptk-faq
ftp://ftp.ccd.bnl.gov/pub/ptk/ 130.199.54.188
ftp://ftp.ccd.bnl.gov/pub/ptk/ptkFAQ.txt 130.199.54.188
ftp://ftp.wpi.edu/perl5/pTk-FAQ 130.215.24.209
ftp://perl.com/pub/perl/doc/ptkFAQ.gz 199.45.129.30
ftp://perl.com/pub/perl/doc/ptkFAQ.ps.gz 199.45.129.30
WWW-FAQ for perl/Tk
http://w4.lns.cornell.edu/~pvhp/ptk/ptkTOC.html
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.html
World Wide Web - perl/Tk info sites
http://pubweb.bnl.gov/~ptk/
http://fxfx.com/kgr/compound/ (Perl Tk Compound Widget Page)
http://w4.lns.cornell.edu/~pvhp/ptk/ptkIMG.html (FAQ image supplement)
http://w4.lns.cornell.edu/~pvhp/ptk/etc/
http://w4.lns.cornell.edu/~pvhp/ptk/misc/
http://w4.lns.cornell.edu/~pvhp/ptk/PNMTYAK/
http://www.mirai.com/wks/
The Mailing list
majordomo@lists.stanford.edu
ptk@lists.stanford.edu
http://www.perl.com/perl/info/books.html
For Perl 5 there is (as of September 1996) a
"New Camel"
by Larry Wall,
Tom Christiansen,
and Randal L. Schwartz,
with Stephen Potter.
Programming Perl 2nd EditionA second edition of the Llama is due out soon too:
Larry Wall, Tom Christiansen, & Randal L. Schwartz with Stephen Potter
(c) 1996 O'Reilly & Associates Inc.
ISBN 1-56592-149-6 (English)
Learning Perl, 2ndEditionThe two early Perl books by Schwartz and Wall are very helpful (even if they do pertain to perl 4 and not 5. Beware that perl/Tk makes extensive use of perl 5 object-oriented features.):
Randal L. Schwartz
June 1997 (est.) O'Reilly & Associates Inc.
ISBN 1-56592-284-0 (English)
Learning Perl (The Llama)
Randal L. Schwartz
Copyright (c) 1993 O'Reilly & Associates Inc.
ISBN 1-56592-042-2 (English)
ISBN 2-84177-005-2 (French)
ISBN 3-930673-08-8 (German)
ISBN 4-89502-678-1 (Japanese)
Programming Perl (The Camel)There is also some Perl5 (book material) information at:
Larry Wall and Randal L. Schwartz
Copyright (c) 1991 O'Reilly & Associates Inc.
ISBN 0-937175-64-1 (English)
ISBN 3-446-17257-2 (German) (Programmieren in Perl, translator: Hanser Verlag)
ISBN 4-89052-384-7 (Japanese)
http://www.metronet.com/1h/perlinfo/perl5/
Jon Orwant (the organizer of the
comp.lang.perl.tk newgroup)
has a book on Perl 5 that has a chapter that discusses the Tk extension.
(Please note that it is mostly
about Perl 5, there is a some discussion of four simple Perl/Tk programs, but
it is not a book wholly devoted to Perl/Tk.) It is nevertheless a good
introduction to object-oriented Perl 5 programming. The relevant info:
Perl 5 Interactive CourseThe Perl 5 Quick Reference Guide (may require LaTeX for installation) can be obtained from any CPAN ftp site. Detailed location information is also available at the author's website:
Jon Orwant
(c) 1996 The Waite Group Press
A Division of SAMS Publishing, Corte Madera, CA USA
ISBN: 1-57169-064-6
http://www.xs4all.nl/~jvromans/perlref.html
The quick reference guide has also been turned into a small Nutshell handbook:
Perl 5 Desktop Reference
Johan Vromans
Copyright (c) February 1996 O'Reilly & Associates Inc.
ISBN: 1-56592-187-9; Order number: 1879
Eric F. Johnson has a book that discusses many perl5 for Unix vs. perl5 for Windows NT issues. He includes a final chapter with extensive discussion of the Tk extension and the ->Text() widget in particular. The information on that book is:
Cross-Platform Perl
(c) 1996 Eric F. Johnson
MIS:Press/M&T Books
ISBN: 1-55851-483-X
Kamran Husain and Robert F. Breedlove have written a perl 5 book that includes a chapter on Tk with some discussion of Menu()s. That book is:
Perl 5 Unleashed
Kamran Husain and Robert F. Breedlove
(c) 1996 Sams Publishing, Indianapolis, IN
ISBN: 0-672-30891-6
There is also a "Perl 5 How-To" book available that contains a great deal of erroneous information about perl/Tk. Among other things that book wrongly mentions that it is necessary to have a complete Tcl/Tk library installed on one's system to compile the Tk extension to perl. (They are incorrect - it is only necessary to have the appropriate perl version, libc and Xlib, the Tk extension is otherwise "self-contained").
There is also a book on perl web client. It features a a chapter on perl/Tk that was written by Nancy Walsh:
Web Client Programming with Perl
Clinton Wong
1st Edition March 1997
O'Reilly & Associates Inc.
ISBN: 1-56592-214-X; Order number: 214X
Additional book information may be found at Tom Christiansen's perl & cgi books page, or at his Perl-related Book Reviews page.
The multi-part perl 5 manual pages are available (assuming they have been installed in your MANPATH, type man perl, man perlmod etc.).
The perl 5 man pages are also available on the web at a number of locations. In general the more recent the documentation the more helpful it is.
In addition to the CPAN ftp source sites, a miscellany of internet perl resources includes:
Newsgroups
comp.lang.perl.misc
comp.lang.perl.announce
comp.lang.perl.modules
comp.infosystems.www.authoring.cgi
comp.answers
news.answers
Perl FAQ-Archives (ftp sites) [Note: FAQ may be many separate files]
(as of 5.004 the FAQ ships in pod format with perl)
(see also the CPAN sites)
North America
ftp://rtfm.mit.edu/pub/usenet/news.answers/perl-faq/
ftp://ftp.uu.net/usenet/news.answers/perl-faq 192.48.96.9
ftp://ftp.khoros.unm.edu/pub/perl/faq.gz 198.59.155.28
Europe
ftp://ftp.cs.ruu.nl/pub/NEWS.ANSWERS/perl-faq/ 131.211.80.17
ftp://src.doc.ic.ac.uk/packages/perl/FAQ 146.169.2.10
Gopher Perl FAQ
gopher://gopher.metronet.com/11/perlinfo/faq
WWW-FAQ for Perl
http://www.perl.com/perl/faq/
http://www.smartpages.com/bngfaqs/comp/lang/perl/top.html
http://www.smartpages.com/bngfaqs/comp/lang/perl/misc/top.html
http://www.smartpages.com/bngfaqs/comp/lang/perl/announce/top.html
http://www.cis.ohio-state.edu/hypertext/faq/usenet/perl-faq/top.html
Perl for Win32 FAQ (discusses Win95)
http://www.perl.org/CPAN/doc/FAQs/win32/Perl_for_Win32_FAQ.html
Perl info sites
Gopher (gopher:70) perl info sites
USA
gopher://gopher.metronet.com/11h/perlinfo
World Wide Web (http:80) perl info sites
USA
http://www.yahoo.com/Computers_and_Internet/Languages/Perl/index.html
http://www.perl.com/
http://www.khoros.unm.edu/staff/neilb/perl/home.html
http://www.khoros.unm.edu:80/staff/neilb/perl/metaFAQ/
http://www.metronet.com/perlinfo/
http://www.metronet.com/perlinfo/perl5.html (Perl 5)
http://www.eecs.nwu.edu/perl/perl.html
http://cesr39.lns.cornell.edu/public/perl/
http://www.virtualschool.edu/mon/Perl.html
http://www.hermetica.com/technologia/unexec/
http://www.oac.uci.edu/indiv/ehood/perlWWW/
http://web.sau.edu/~mkruse/www/scripts/
http://orwant.www.media.mit.edu/the_perl_journal/
http://www.perl.com/Architext/AT-allperl.html
http://www.mispress.com/introcgi/
http://www.walrus.com/~smithj/webcan/
http://web.syr.edu/~chsiao05/cps600_project.html
http://www.iftech.com/classes/webdev/webdev_perl.htm
http://www.cc.iastate.edu/perlmenu/
http://www.ora.com/www/item/cgi_prog.html
UK
http://pubweb.nexor.co.uk/public/perl/perl.html
http://www.bio.cam.ac.uk/web/form.html
Web references to Perl mailing lists
http://www.perl.com/perl/info/mailing-lists.html
http://www.nicoh.com/cgi-bin/lwgate/PERL5-PORTERS/
http://www.hut.fi/~jhi/perl5-porters.html
http://www.rosat.mpe-garching.mpg.de/mailing-lists/
Tcl and the Tk Toolkit
John K. Ousterhout
Copyright (c) 1994 Addison-Wesley Publishing Company
ISBN 0-201-63337-X (alk. paper)
LOC QA76.73.T44097 1994; 005.13'3--dc20
Practical Programming in Tcl and Tk
Brent Welch
Copyright (c) 1995 Prentice Hall
ISBN 0-13-182007-9
Within the tclsh or wish shells your manpath
includes the tcl/tk man pages (which may not be in your login
MANPATH). Thus from the % prompt within either shell type commands
like:
% man -k Tk
The Tcl/Tk Reference Guide is also a source of useful information. Although it's Tcl specific most perl/Tk commands can be, more or less, easily derived from it. [Note that in perl/Tk the names of some functions and some configuration options have changed slightly from their Tcl/Tk counterparts. With recent versions of perl/Tk a great many functions start with an upper case letter and continue with all lower case letters (e.g. there is a perl/Tk Entry widget but no entry widget), and many configuration options are all lower case (e.g. there is a perl/Tk highlightthickness option but no highlightThickness option).] You may fetch the Tcl/Tk Reference Guide (may require LaTeX for installation) from:
ftp://ftp.slac.stanford.edu/software/TkMail/tkref-4.0.1.tar.gz 134.79.18.30 ftp://ftp.aud.alcatel.com/tcl/docs/tkref-4.0.1.tar.gz 198.64.191.10There are a number of other Tcl/Tk resources on the internet including:
Newsgroups
comp.lang.tcl
comp.lang.tcl.announce
comp.infosystems.www.authoring.cgi
comp.answers
news.answers
FAQ-Archive (ftp) [Note: Tcl FAQ may be many files, Tk FAQ is one file]
ftp://ftp.aud.alcatel.com/tcl/docs/ 198.64.191.10
ftp://rtfm.mit.edu/pub/usenet/news.answers/tcl-faq
ftp://rtfm.mit.edu/pub/usenet/news.answers/tcl-faq/tk
WWW-FAQ for Tcl/Tk
http://www.teraform.com/%7Elvirden/tcl-faq/
http://www.smartpages.com/faqs/tcl-faq/top.html
http://www.smartpages.com/bngfaqs/comp/lang/tcl/top.html
http://www.cis.ohio-state.edu/hypertext/faq/usenet/tcl-faq/top.html
http://www.cis.ohio-state.edu/hypertext/faq/bngusenet/comp/lang/tcl/top.html
http://www.sco.com/Technology/tcl/Tcl.html
World Wide Web - Tcl/Tk info sites
Canada
http://web.cs.ualberta.ca/~wade/Auto/Tcl.html
UK
http://http2.brunel.ac.uk:8080/~csstddm/TCL2/TCL2.html
http://www.cis.rl.ac.uk/proj/TclTk/
USA
http://www.yahoo.com/Computers_and_Internet/Languages/Tcl_Tk/index.html
http://www.sunlabs.com/research/tcl/docs.html
http://www.sunlabs.com/research/tcl/4.0.html
http://www.sco.com/Technology/tcl/Tcl.html
http://www.neosoft.com/tcl/
http://www.elf.org/tcltk-man-html/contents.html
Tcl/Tk - miscellaneous extensions
ftp://ftp.cme.nist.gov/pub/expect/
http://www.cs.hut.fi/~kjk/porttk.html
http://www.cis.upenn.edu/~ioi/tix/tix.html
http://www.ece.cmu.edu/afs/ece/usr/svoboda/www/th/homepage.html
http://www.tcltk.com/ [incr Tcl]
http://www.neosoft.com/tcl/TclX.html
http://www.eolas.com/eolas/webrouse/tcl.htm [WebWish]
http://www.se.cuhk.hk/~hkng2/big5tk/big5tk.html
http://www.cs.uoregon.edu/~jhobbs/work/ [BLT etc.]
There are a number of X resources on the internet including:
Newsgroups
comp.windows.x
comp.windows.x.announce
comp.windows.x.apps
X FAQs:
ftp://ftp.x.org/contrib/faqs/
X FAQ on the World Wide Web:
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-1
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-2
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-3
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-4
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-5
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-6
http://www.x.org/ftp/contrib/faqs/x-faq-multipart/x-faq-7
X Window System book info on the Web:
http://www.x.org/ftp/contrib/docs/Xbibliography.OReilly
http://www.ora.com/catalog/v1/
http://www.ora.com/catalog/v2/
http://www.ora.com/catalog/v3/
http://www.ora.com/catalog/v4/
http://www.ora.com/catalog/v5/
http://www.ora.com/catalog/v6a/
http://www.ora.com/catalog/v6b/
http://www.ora.com/catalog/v6c/
http://www.ora.com/catalog/r6/noframes.html
http://www.ora.com/oracom/prog/flanart.html
World Wide Web - X Window System info sites
http://www.x.org/
http://www.x.org/consortium/GettingX.html
http://www.x.org/consortium/x_info.html
http://www.x.org/consortium/R6.1doc/man/X11/
http://www.wolfram.com/~cwikla/widget/
http://www.zeta.org.au/~rosko/pigui.htm
http://www.rahul.net/kenton/xsites.html
http://www.unx.com/DD/txaCurrent.shtml
Return to table of contents
8. How do I write scripts in perl/Tk?
Start your script as you would any perl script (e.g.
#!/usr/bin/perl, #!/usr/local/bin/perl,
#!/opt/bin/perl, [built static? then
#!/usr/bin/tkperl], whatever, see the
perlrun(1) man page for more information).
Throwing the -w warning switch is recommended.
The use of the statement use strict; is recommended.
Use of the statement use Tk; is required.
A simple "Hello World!" widget script could be written as follows:
#!/usr/local/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
$main->Label(-text => 'Hello World!'
)->pack;
$main->Button(-text => 'Quit',
-command => sub{exit}
)->pack;
MainLoop;
The MainLoop; statement is the main widget event handler
loop and is usually found in perl/Tk scripts (usually near the end of
the main procedure after the widgets have been declared and
packed). MainLoop; is actually a function call and you
may see it written as MainLoop();, &Tk::MainLoop;,
&Tk::MainLoop();, etc.
Note the use of the -> infix dereference operator. Most things in calls to perl/Tk routines are passed by reference.
Note also the use of the => operator which is simply a synonym for the comma operator (well it is a bit more than that :-). In other words, the arguments that get passed to Label and Button in the above example are good old perl associative arrays (perl 5 people prefer to call them "hashes" however). Indeed, we might have written the above as:
#!/usr/local/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
$main->Label(-text , 'Hello World!'
)->pack;
$main->Button(-text , 'Quit',
-command , sub{exit}
)->pack;
MainLoop;
Or even as:
#!/usr/local/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
my %hello = ('-text','Hello World!');
my %quit_com = ('-text' => 'Quit', '-command' => sub{exit});
$main->Label(%hello)->pack;
$main->Button(%quit_com)->pack;
MainLoop;
Note however, that the use of the => in the first
method of writing this script makes it look more
"Tcl-ish" :-).
Lastly, we note the extensive use of the my function in most perl/Tk programs. my is roughly equivalent to local in Perl 4 - but is purported to be "faster and safer" as well as much more strictly local in scope. See perlfunc(1) manpage for more information on my.
Other examples of code may be found in the perl5/Tk/demos/ directory and in perl5/Tk/demos/widget_lib/.
(A variant on this scipt called hello is available in the
file perl5/Tk/demos/hello in your own pTk distribution.
Also, Source code for this and other examples
from UserGuide.pod may be
found at http://w4.lns.cornell.edu/~pvhp/ptk/pod/.
To load code from the web save as a local filename,
edit the first line to point to your perl interpreter, then:
chmod u+x filename, then execute:
filename.)
Return to table of contents
9. What widget types are available under perl/Tk?
The following Tk widget primitives are available under perl/Tk:
A good introduction to the primitives and how they may be used in conjunction with each other may be found in the widget demo script. Note that all the widget demos have a "Show Code" button. To help figure out what is happening in the script you may, when the window appears, edit the text and instrument the code with print statements and then simply press "Rerun Demo". Another place to see examples of the primitives (on the web) is at the image supplement to this FAQ at the following URL:
http://w4.lns.cornell.edu/~pvhp/ptk/ptkIMG.html
Return to table of contents
10. How do I get widget X to do Y ?
There are a number of tasks that can be accomplished with perl/Tk widgets, configurations, and bindings (a few that can't and a few that require specific tricks). Beginners are encouraged to work through the examples in UserGuide.pod. Some examples from UserGuide.pod are addressed in this document among those that follow.
Basically a widget can be "created" by simply calling the sub of the same name:
my $main = new MainWindow;
will set aside the necessary system memory etc. for a new
MainWindow widget (it does not appear until after the
MainLoop; call). The object "created" is then callable
via the variable $main. So, for example, if you wanted a
Button in your MainWindow, then this:
$main->Button();
would be a very basic example of a widget command. If you wanted to later call
this button widget you would need a "widget tag or ID" to "get a
handle on it". Instead of the above call try something like:
my $button = $main->Button();
The variable $button is how you refer to the Button widget in
subsequent calls, such as when we call the pack routine:
$button -> pack;
A complete script that incorporates these ideas to make a very plain button
would look like:
#!/usr/bin/perl -w
use Tk;
use strict;
my $main = new MainWindow;
my $button = $main -> Button();
$button -> pack;
MainLoop;
But who wants such a plain looking button? You can provide a number of
different widget configurations via calls to the configure routine
as in:
#!/usr/bin/perl -w
use Tk;
use strict;
my $main = new MainWindow;
my $button = $main->Button();
$button -> configure(-text => 'Press me!');
$button -> pack;
MainLoop;
The Perl motto is "there is more than one way to do it." - perl/Tk
remains quite true to this motto as well. Note that the above script could
have been written quite succinctly without the use of either the
$main or $button variables as:
#!/usr/bin/perl -w
use Tk;
use strict;
new MainWindow -> Button(-text => 'Press me!') -> pack;
MainLoop;
But if you want your widgets to actually do things then you must set
up callback procedures as discussed later...
Do not overlook the - sign in front of some options (like -text in the above example) Another commonly overlooked problem is that elements in a hash are supposed to be strings hence a configuration option like -length +> 5, really ought to be specified as either '-length' +> 5, or "-length" +> 5, etc., rather than perl's builtin length() function.
Return to table of contents
10.1. How do I get a Button to call a Perl subroutine?
You may specify the -command option in the call to create & pack the button as in:
$main->Button(-text => 'Print',
-command => sub{do_print($filename, $font)}
)->pack;
Where sub do_print { } is a subroutine that handles two arguments
and is declared elsewhere in the script. A full script example of the use of
the above code is presented in the second example(s)
in UserGuide.pod
(Full source code for this and other examples from UserGuide.pod may be found at http://w4.lns.cornell.edu/~pvhp/ptk/pod/. To load code from the web save as a local file say ex1.pl, edit the first line to point to your perl interpreter, then change permission: %chmod u+x ex1.pl, then execute the script: %ex1.pl.)
The above method is called the "anonymous subroutine (closure)" method. As discussed in Callback.pod one might have re-written that statement to use the "reference to a sub" method thusly:
$main->Button(-text => 'Print',
-command => [ \&do_print , $filename, $font ]
)->pack;
Note the backslash in front of \&do_print. This causes perl to
generate a reference to sub do_print rather than call it.
(thanks Jim Stern :-)
Return to table of contents
10.2. How do I get a Button to actively change under my mouse pointer?
You should specify both an '-image' and an '-activeimage' configuration option either when calling the ->Button() method or in a later separate call to the ->configure() method.
Here is an example excerpted from the basic_demo script that comes with the Tk kit:
#!/usr/local/bin/perl -w
use Tk;
$main = MainWindow->new;
$QPBFile = "demos/images/QuitPB.xpm";
$QPBaFile = "demos/images/QuitPBa.xpm";
$QuitPB = $main->Pixmap('-file' => Tk->findINC("$QPBFile"));
$QuitPBa = $main->Pixmap('-file' => Tk->findINC("$QPBaFile"));
my $but = $main->Button('-image' => $QuitPB,
'-activeimage' => $QuitPBa,
'-command' => sub { $main->destroy }
) -> pack;
MainLoop;
__END__
Return to table of contents
10.3. How do I arrange the layout of my widgets?
To control the layout and appearance of widgets in a window one makes use of a geometry manager, as well as -padding, -fill, -expand, and -anchor options of individual widgets.
A geometry manager is any Tk procedure for controlling the arrangement of widgets in your application window. The predominant geometry manager used in both Tcl/Tk and perl/Tk is pack also known informally as the "packer" (other geometry managers are the "placer" and the canvas widget itself but are much less popular. There is also Nick Ing-Simmon's Table widget [discussed in a later question] and BLT_Table [which made it's way into perl/Tk thanks to Guy Decoux - but is also discussed in a later question]. So far tixForm is for Tcl/Tk only, but a perl/Tk version of Tix is in the works. You can invoke pack at the time of widget creation via calls like:
$widget->pack;
where widget can be any of the perl/Tk widget primitives. Widget option
lists are usually passed as an associative array (hash) in parentheses thusly:
$widget(-option0 => value0,-option1 => value1)->pack;
pack is often used in conjunction with the frame
container widget to arrange your widgets much like a hiearchically arranged
set of window panes (ultimately in a rectangular "tiling" fashion of
sorts). An example of this would be:
my $top2 = $main->Toplevel;
my $frame = $top2->Frame;
$frame->pack;
$frame->Label(-text => 'Left2')->pack(-side => 'left');
$frame->Label(-text => 'Right2')->pack(-side => 'right');
$top2->Label(-text => 'Bottom2')->pack(-side => 'bottom');
MainLoop;
Note that pack itself is given parameters in this example. The
default behavior for pack is equivalent to specifying
-side => 'top' which can be overridden as in the above example.
(Full source code for this and other examples from UserGuide.pod may be found at http://w4.lns.cornell.edu/~pvhp/ptk/pod/. To load code from the web save as a local file say ex2.pl, edit the first line to point to your perl interpreter, change permission using: chmod u+x ex2.pl, then type the name of your script: ex2.pl.)
One of the more helpful options to pass to pack when trying to get a given widget layout "just right" is through padding: either -padx or -pady. The details of the use of pad depend on which specific widget you are trying to pack. In fact you can often add the -pad in the call to create the widget rather than in the call to pack.
There is also the -anchor configuration option for widgets. A good introduction to the 9 possible -anchor (and -overanchor) values is given by the popup demo in your perl/Tk build directory.
When setting a widget within a frame next to another widget one may wish to make use of the -fill => 'style' (where style = none | x | y | both) options of either pack or the widget itself. A typical situation where this is used is in setting up the Scrollbar next to a Canvas or Text widget.
Another aspect to consider when laying out your widgets is their behavior under resize operations (grabbing a part of the window frame and making it bigger or smaller - details depend on your window manager). This may be controlled by the -expand option of either pack or the widget itself.
Return to table of contents
10.4. How do I get a Popup to popup?
For things like a simple "are you sure?" dialog box you might want to take a look at Dialog.pm which is discussed in a later question within this FAQ [16.1].
If you don't wish to require Tk::Dialog, you need something more complicated, or you simply want to create your own independent window with widgets; you must first setup a Toplevel in perl/Tk. The fourth example in UserGuide.pod gives a simple example of how to call Toplevel. Quoting from that script:
my $main = new MainWindow;
fill_window($main, 'Main');
my $top1 = $main->Toplevel;
Where sub fill_window is declared after the call to
MainLoop;. When running that script take
careful note of which window pops up first, which window has grabbed
the active attention of your input device(s), and which widget within the
active window has the keyboard/mouse focus when all three windows are
open.
The use of Toplevels brings up the issue of grab - or which independent window is presently "active" and which are activatable. To make a Toplevel window active call grab thusly:
$Top_widget->grab(grab_option);
where $Top_widget identifies the desired Toplevel
(it would be either $top1 or $top2 in the
sample script referred to above).
grab_option could be -global - but this is
discouraged as a sign of "desparate programming style". To give a
Toplevel "local grab" you may simply say:
$Top_widget->grab;
That is, without an argument.
The use of Toplevels may also bring up the issue of focus - or which window - even which widget within a window - is presently "hot". You may call focus on an entire Toplevel:
$Top_widget->focus;
However, focus is most often used with individual widgets rather
than a whole Toplevel.
To de-iconify a widget there is in fact a Popup function that may be called thusly:
$Top_widget->Popup();
Return to table of contents
10.5. How do I bind keyboard keys?
There are many default key bindings built in to the widgets of perl/Tk. Making proper use of them often involves setting up the right callback. (You may wish to consult the examples in BindTable.pod for help with this subject.)
The basic idea is:
$widget -> bind('<keyname>' => action);
Where $widget is the tag or ID of the widget for which the
bindings are to hold (note for global bindings you have to bind to
<All>, for semi-global bindings you need to bind
to all the relevant widgets in your application), '<keyname>'
can be things like:
<Key> or <KeyPress> or <Any-KeyPress>
<KeyRelease>
<Button> or <ButtonPress>
<ButtonRelease>
<Button-1> or <B1>
<Double-1>
<Enter>
<Leave>
<Motion>
To figure out what names perl/Tk uses for such <bindings> use the
"binder-finder" on a widget's .pm file. For example, you could find
bindings hidden inside of Button.pm by typing this at your
shell prompt:
perl -ne 'print if s/.*(<[^>]*>).*/$1/g;' Button.pm
while in the directory where Button.pm is located (and if you are
not there then simply specify the /path/to/Button.pm).
Note that due to inheritance (e.g.the type of script bindings that are
being discussed here) what the binder-finder turns up may not be the last word
on a given widget's behaviour. This may be especially true for a widget inside
of a compound/composite widget.
Note also that the binder-finder will turn up things like <FILEHANDLES>
as well as honest <Bindings>. Discrimination in its use is called for
(and while your at it you could have just as easily used an editor and actually
examined the code directly now couldn't you?).
To get an idea of what the code is for a key that you are interested in try running the xlib_demo that comes in your perl/Tk build directory. Hold your mouse pointer over the window that appears and simply type the key that you are interested in. The code should appear in the window. If you do not have perl/Tk up and running yet try "xmodmap -pk" or look directly at the /usr/include/X11/keysymdef.h file where keysym names are given with an XK_ pre-pended. Do not try things like the Tcl/Tk %k symbols in perl scripts. %Ks will be mis-interpreted as non-existant perl hashes. Instead look at the Xevent function.
Ali Corbin <corbin@adsw.fteil.ca.boeing.com> recently posted a great little script for determining keyboard key bindings on a MainWindow:
#!/usr/local/bin/perl -w
use Tk;
$top = MainWindow->new();
$frame = $top->Frame( -height => '6c', -width => '6c',
-background => 'black', -cursor => 'gobbler' );
$frame->pack;
$top->bind( '<Any-KeyPress>' => sub
{
my($c) = @_;
my $e = $c->XEvent;
my( $x, $y, $W, $K, $A ) = ( $e->x, $e->y, $e->K, $e->W, $e->A );
print "A key was pressed:\n";
print " x = $x\n";
print " y = $y\n";
print " W = $K\n";
print " K = $W\n";
print " A = $A\n";
} );
MainLoop();
To bind the action of one widget to that of another try taking a
look at the .pm file for the widget of interest - is there a binding
function already defined? If so you may use it. An example would be the use of
"Up" & "Down" Buttons for a
Listbox: one could bind the Buttons to call
Tk::Listbox::UpDown, however, Guy Decoux describes a much more
clever way to use the <Up> and <Down> already
defined in Listbox.pm (this does not work with Tk-b9.01):
#!/usr/local/bin/perl
use Tk;
$top = MainWindow->new;
$lb = $top->Listbox(-height => 10);
for($i=0; $i < 120; $i++) {
$lb->insert('end', $i);
}
$f = $top->Frame;
$up = $f->Button(
-text => "Up",
-command => [ $lb->bind(ref $lb, '<Up>'), $lb]
);
$down = $f->Button(
-text => "Down",
-command =>sub {&{$lb->bind(ref $lb, '<Down>')}($lb)}
);
$up->pack(-side => 'left');
$down->pack;
$f->pack;
$lb->pack;
MainLoop;
Return to table of contents
On Fri, 15 Sep 95 10:30:56 BST Nick Ing-Simmons <Nick.Ing-Simmons@tiuk.ti.com> writes:
Re: Multiple binds to a single widget? ************************************** On Thu, 14 Sep 1995 14:57:54 -0400 Alain St <astdenis@cmc.doe.CA> writes: !In the tcl/tk doc I have, they say that prepending the script !with '+' appends the new binding to the current one. ! !How do I do that in perlTk? !
You cannot do that that way (yet?) - one issue is what it would mean to prepend '+' to a perl/Tk callback :
$widget->bind('<A>','+',[\&subname,$arg]);
# did not look right to me
Other issue is that I would need to manage a list-of-callbacks in glue code.Bind your new command to a new tag:
$widget->bind('Extra',....);
And add Extra to the widgets bindtags:
$widget->bindtags([ref($widget),$widget,'Extra',
$widget->toplevel,'all']);
Return to table of contents
10.7. How do I bind the action of a slider (sic) to ... ?
Technically speaking they are called Scrollbars (not sliders) and one
must configure the action of the desired widget to call the
Scrollbars (i.e. bind is not involved here)
A common task using Scrollbars is to configure things like Canvas, Listbox, or a Text widgets to be updated (change appearance) when the slider of the acompanying Scrollbar is moved by the user.
As an example consider the code that sets up a twelve element Listbox and an accompanying vertical Scrollbar:
my $main = new MainWindow;
my $box = $main->Listbox(-relief => 'sunken',
-width => -1, # Shrink to fit
-height => 5,
-setgrid => 'yes');
my @items = qw(One Two Three Four Five Six Seven
Eight Nine Ten Eleven Twelve);
foreach (@items) {
$box->insert('end', $_);
}
my $scroll = $main->Scrollbar(-command => ['yview', $box]);
So far so good. But merely setting them up does not mean that the
Listbox even knows that the Scrollbar is lying next to
it. Note that the scalar variable $scroll is how we
refer to the Scrollbar, thus, hooking the $box up to
handle $scroll events is a matter of configuration:
$box->configure(-yscrollcommand => ['set', $scroll]);
A complete script that makes use of this code (and adds the necessary
calls to pack and MainLoop;) is given as
the fifth example in
UserGuide.pod (and may be
found at http://w4.lns.cornell.edu/~pvhp/ptk/pod/.)
There was an old Perl/Tk tendency to have a bunch of ScrlFoo widgets (such as ScrlListbox). The use of such widgets is now deprecated in favor of a new Scrolled class, as in:
$w = $patent->Scrolled('Text',...);
The widgets that can be ->Scrolled() include:
Return to table of contents
10.8. How do I configure a Scrollbar to scroll multiple widgets?
Note that the widget type that you wish to scroll can be important as a scroll "unit" on a Text or Listbox may be a character (several pixels - depending on font) whereas it would be an X "units" on a Canvas (could be pixel - but you may also specify other units).
A concrete answer for scrolling 3 Listboxes comes courtesy of Frederick L. Wagner <derf@ti.com>:
From a working example of multi-xscrolling:
sub multiscrollx
{ # multiscrollx
my ($sb,$wigs,@args) = @ARG;
my $w;
foreach $w (@$wigs)
{
$w->xview(@args);
}
} # multiscrollx
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
$sh->configure( -command => [ \&multiscrollx, $sh,
[$scratchrule,$ruleheader,$ruletable]]);
$ruletable->configure( -xscrollcommand => [ 'set', $sh]);
$ruleheader->configure( -xscrollcommand => [ 'set', $sh]);
$scratchrule->configure(-xscrollcommand => [ 'set', $sh]);
In this case,
$sh is a horizontal Scrollbar,
$ruletable and $scratchrule are Tables
$ruleheader is an Entry
However, this approach is good for any widget with X-scrolling capability, I think. So the Y counterpart should be:
sub multiscrolly
{ # multiscrolly
my ($sb,$wigs,@args) = @ARG;
my $w;
foreach $w (@$wigs)
{
$w->yview(@args);
}
} # multiscrolly
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
$sv->configure( -command => [ \&multiscrolly, $sv,
[$l1,$l2,$l3]]);
$l1->configure( -yscrollcommand => [ 'set', $sv]);
$l2->configure( -yscrollcommand => [ 'set', $sv]);
$l3->configure( -yscrollcommand => [ 'set', $sv]);
Hope that helps.
Greg VanSickle <vansickl@bnr.ca> points out that this little script snippet does not provide for the binding of '<Button-2<' that he is accustomed to. He wrote a package called DSListbox to address this binding issue.
Conversely, Jong Park asked how to setup multiple Scrollbars to scroll the same widget. Nick Ing-Simmon's reply makes use of an anonymous sub and can be summed up in a little script that scrolls a Text widget (to see the scrolling in action type more than 20 lines of text into the widget):
#!/usr/local/bin/perl -w
use Tk;
my $mw = MainWindow->new();
my $s1 = $mw->Scrollbar(-orient => 'vertical');
my $s2 = $mw->Scrollbar(-orient => 'vertical');
$s1->pack(-side => 'left', -fill => 'y');
my $t = $mw->Text(
-yscrollcommand => sub{$s1->set(@_), $s2->set(@_)},
-wrap => 'word',
-width => 70,
-height => 20,
-font => $font,
-setgrid => 1,
)->pack(-side => 'left');
$s2->pack(-side => 'right', -fill => 'y');
$s1->configure(-command => [$t => 'yview']);
$s2->configure(-command => [$t => 'yview']);
MainLoop;
__END__
Return to table of contents
10.9. How do I display a bitmap?
You can display X bitmaps on your widgets with the -bitmap configuration option. Typically -bitmaps are configured into Label, Frame, Button, etc. widgets (Canvas widgets are another story however see question [11.1] below). In order to emphasize the bitmap option itself let us assume we were specifying a bitmap for a Label with a call like:
$main->Label(-bitmap => 'bitmap-name')->pack;
Where bitmap-name could be any of the built in Tk bitmaps:
error, gray25, gray50, hourglass,
info, question, questhead,
warning (see the widget demo for a full list).
In order to use some of the bitmaps in the perl5/Tk/demos/images/ directory you would specify a fuller path name like:
$main->Label(-bitmap => "\@$tk_library/demos/images/face")->pack;
Note the escaped "\@" on the directory specification (as
well as the use of the $tk_library variable imported by use
Tk;). If you wanted to specify a file called foobar.xbm in
the directory where you were running the script then either:
$main->Label(-bitmap => '@foobar.xbm')->pack;
#or
$main->Label(-bitmap => "\@foobar.xbm")->pack;
should work just fine. In another directory however that would be a problem.
So something like:
$main->Label(-bitmap => "\@$ENV{'HOME'}/img/foobar.xbm")->pack;
will help someone who has an img/foobar.xbm file in their $HOME
directory. If you don't mind the non-portability then hard-wiring in the full
path name will help as well. (Or if you have write access then put your files
in Tk/demos/images/ e.g.)
Return to table of contents
10.10. How do I display an image?
You will want to get a "Photo" handle on the file as in the following example where 'imggif' is the Photo handle for a gif file that is distributed with perl/Tk:
#!/usr/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
$main ->Label(-text => 'Main')->pack;
$main -> Photo('imggif',
-file => "$Tk::tk_library/demos/images/earth.gif");
my $l = $main->Label('-image' => 'imggif')->pack;
$main->Button(-text => 'close',
-command => sub{destroy $main}
)->pack(-side => 'left');
$main->Button(-text => 'exit',
-command => [sub{exit}]
)->pack(-side => 'right');
MainLoop;
(Canvas widgets are another story however
see question a later question within this FAQ).
Return to table of contents
10.11. What Image types are available?
In addition to the Tk builtin bitmaps there is support for reading images from files in formats such as: X11 Bitmaps (.xbm), X Pixmaps (.xpm), and Graphics Inline Format (.gif). See the CrtPhImgFmt man page for more info (if you have Tk 4.X installed). (In order to support other formats you might also consider running through a netpbm filter.)
For perl generation of images see the question (later in this FAQ) on graphics modules.
Return to table of contents
10.12. Is there any way to have more than one Listbox contain a selection?
To allow more than one Listbox to contain a "selection", (or at least a highlighted item - which need not be the actual selection) specify the configuration option:
-exportselection => 0
which will dis-associate Listbox's selection from X selection
(only one window can have X selection at a time).
Here is a rather simple script that illustrates what happens when only one Listbox has -exportselection => 0 specified:
#!/usr/bin/perl -w
use Tk;
my $main = MainWindow->new;
my @fruits = ('Apple','Banana','Cherry','Date','Elderberry','Fig');
my @nuts = qw(Almond Brazil Chestnut Doughnut Elmnut Filbert);
my $fruit_list = $main->Listbox();
for (@fruits) { $fruit_list -> insert('end',$_); }
$fruit_list->pack();
my $fruitprint_button = $main->Button(
-text => "print selection",
-command => sub{ printthem($fruit_list) }
)->pack;
my $nut_list = $main->Listbox(
-selectmode => 'multiple',
-exportselection => 0,
)->pack;
for (@nuts) { $nut_list -> insert('end',$_); }
my $nutprint_button = $main->Button(
-text => "print selection(s)",
-command => sub{ printthem($nut_list) }
)->pack;
my $quit_button = $main->Button(-text => "quit program",
-command => sub{exit},
)->pack();
MainLoop;
sub printthem {
my $list = shift;
my @entries = $list->curselection;
for (@entries) { print $list -> get($_),"\n";}
}
For a more extensive example of Listbox usage combined with some
perl data structure exploitation see the script at:
http://w4.lns.cornell.edu/~pvhp/ptk/etc/lb-constructor
Return to table of contents
10.13. How do I select a range of tags in a Text widget?
A question arose concerning getting a range of selections from a Text widget. Nick Ing-Simmons' answer mentions several possibilities including:
Keyboard Copy/Paste 'is' implemented of course...
Subj: RE: $Text->tag('ranges', 'sel') - does this work?
In <199512291957.OAA02609@ohm.nrl.navy.mil>
On Fri, 29 Dec 1995 14:57:42 -0500
Charles J Williams <chas@ohm.nrl.navy.mil> writes:
!I was writing a little tk perl today, and i decided to try to
!implement a copy/paste using the 'sel' tag
!
!I enabled exportselection, and then try to probe the select
!region with:
!
! $buffer = $text->tag('ranges', 'sel');
!
!$buffer comes back with one entry, the end of the selection.
That is to be expected - the scalar gets assigned the last element of the list.
!I tried:
!
! @buffer = $text->tag('ranges', 'sel');
!
!same difference.
This seems to work for me:
($start,$end) = $text->tagRanges('sel');
In perl/Tk ->tagRanges(...) is an alias for ->tag('ranges',...)The following subroutine can also probe and print the tagRanges:
sub showsel
{
my $text = @_;
my @info = $text->tagRanges('sel');
if (@info)
{
print "start=$info[0] end=$info[1]\n"
}
}
Return to table of contents
10.14. How do I group Radiobuttons together?
Specify the -variable option on each one. Here is an example pulled from the icon.pl demo script:
$letters = '';
my $w_frame_left_b3 = $w_frame_left->Radiobutton(
-bitmap => "\@$tk_library/demos/images/letters",
-variable => \$letters,
-value => 'full',
);
my $w_frame_left_b4 = $w_frame_left->Radiobutton(
-bitmap => "\@$tk_library/demos/images/noletters",
-variable => \$letters,
-value => 'empty',
);
Return to table of contents
10.15. How do I specify fonts?
The quick answer is to specify the font configuration option of your widget as in:
#!/usr/local/bin/perl -w
use Tk;
$main = MainWindow->new();
$labl = $main -> Label('-text' => "Foo", '-font' => "fixed");
$labl -> pack;
MainLoop;
The long answer involves figuring out what fonts you have access to locally.
The Unix programs xlsfonts and xfontsel are useful in this
regard.
The perl/Tk version of xfontsel was distributed as the font_test script in the Tk build directory.
See also the later question (within this FAQ) on international fonts.
Return to table of contents
10.16. How do I get the entry in an Entry?
You want to call get on the return value of the widget itself. Here is how it may be used in a simplified version of example 1.1 from the Tk::UserGuide where a Button is set up to call a sub where the call to get lies:
#!/usr/bin/perl -w
use strict;
use Tk;
my $main = MainWindow -> new();
my $entry = $main -> Entry();
$entry -> pack;
$main->Button(-text => 'Print',
-command => sub{do_print($entry)}
)->pack;
MainLoop;
sub do_print {
my ($widget) = @_;
my $entered = $widget -> get();
print "The string \"$entered\" was entered.\n";
}
Return to table of contents
10.17. How do I hide a password Entry?
Set the -show option to zero, as in this example:
$entry = $form->Entry(-textvariable => \$user_entry,
-show => 0);
Return to table of contents
10.18. How do I limit an Entry's insertion width?
Nick Ing-Simmons recommends writing a new Entry widget with the insert method appropriately overridden by one that does limit the width. His code is avaialable as a separate package from:
http://w4.lns.cornell.edu/~pvhp/ptk/etc/LEntry-0_00.tar.gz
Now Brent Powers points out a possible problem with that approach and
recommends an insert() method as follows:
Date: Thu, 22 Aug 1996 10:32:44 -0400
From: "Brent B. Powers" <powers@ml.com>
Subject: Re: How to set max characters for Entry widget
In-reply-to: <199608211445.PAA09248@pluto>
Ummm, before we set this into the distribution or FAQ, maybe we should
make it work properly. An example: Imagine maxwidth configured to 8,
the user fills in ABCDEFGH, moves the cursor back 4 places, and types
I. The SUPER::insert call sets the string to ABCDIEFGH, which this
code then modifies to ABCDIEFG.
Hmmm, how about
sub insert {
my($w, @args) = @_;
my($max) = $w->cget(-maxwidth);
my($sval) = $w->get;
if (length($sval) >= $max) {
$w->SUPER::insert(@args);
if (length($w->get) > length($sval) {
## Reject it;
my($idx) = $w->index('insert'); # get current cursor position
$w->delete(0, 'end');
$w->insert(0, $sval);
$w->icursor($idx);
$w->bell;
} else {
$w->SUPER::insert(@args);
}
}
Of course, that still doesn't deal with the selection, but ...
To which Nick Ing-Simmons responded (Thu Aug 22 1996):
'paste' and <ButtonRelease-2> call insert method, what other selection
issues are there?
Return to table of contents
10.19. How do I obtain Menus that do not tear off?
Nick Ing-Simmons outlined a couple of ways to achieve this result. The critical feature being the -tearoff => 0 configuration option of the Menu. In Nick's words:
my $mb = $parent->Menubutton(...); # The button
my $menu = $mb->Menu(-tearoff => 0); # Create a non-tearoff menu
$mb->configure(-menu => $menu); # Tell button to use it.
$mb->command(....);
Above is for clarity - you can loose $menu variable:
my $mb = $parent->Menubutton(...);
$mb->configure(-menu => $mb->Menu(-tearoff => 0));
$mb->command(....);
Return to table of contents
11. How do I get a Canvas to ... ?
The Canvas widget is the most configurable and versatile. With versatility comes complication however, and it is certainly deserving of its own special section within this FAQ...
You might also see the examples in the widget demo especially the "canvas item types" selection (which runs the items.pl demo script).
Return to table of contents
Unlike other widgets the Canvas does not take the -bitmap configuration option. One of the ways to place things - including bitmaps - onto a Canvas is to call create on it. To emphasize how a Canvas handles bitmaps differently from the configurable widgets let me assume that you wanted to specify the 'hourglass' built in bitmap in the following. (For more on xbm file specification see a previous question [10.9] within this FAQ.) Here is a way to combine the Canvas; and create; calls:
my($canvar) = $main->Canvas();
my($bittag) = $canvar->create('bitmap',10,10, -bitmap=>'hourglass');
$canvar->pack;
You can also create an image that will display a bitmap (plus a
whole lot more):
my($canvar) = $main->Canvas();
my($bitmap) = $main->Bitmap(-data => $data);
my($bittag) = $canvar->create(qw(image 10 10), -image => $bitmap);
$canvar->pack;
MainLoop;
Return to table of contents
To erase something like a bitmap call delete on the item. Assuming your Canvas tag is $canvar and your item tag it $bittag (as in the previous [11.1] question) then the call proceeds like:
$canvar -> delete($bittag);
This is of course useful in a callback. For example to configure a
Button to do your deletion for you you could say something like:
$main->Button(-text => 'clear',
-command=>sub{$canvar -> delete($bittag)}
)->pack;
To remove an entire MainWindow() call the withdraw()
method:
$main -> withdraw;
Return to table of contents
Just as for the other widget types there is a two step process of first getting a "Photo" handle on the file of interest. For the Canvas (unlike the other widgets) one then makes a call to create an image as in the following example where 'IMG' is the Photo handle for a GIF file that comes distributed with the Tk kit (it just happens to be handled in this example via the scalar variable $img):
#!/usr/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
my $canvar = $main ->Canvas;
$canvar->pack;
my $file = 'demos/images/earth.gif';
my $img =
$canvar->Photo( 'IMG',
-file => Tk->findINC($file) );
$canvar->create( 'image',0,0,
'-anchor' => 'nw',
'-image' => $img );
MainLoop;
__END__
Return to table of contents
11.4. What things can be created on a Canvas?
The following types can be used in $canvar->create calls:
arc sections of circle
bitmap for X11 bitmap files/builtins
image for Photo image types (gif, xpm, xbm, ...)
line
oval includes circles
polygon may be -filled
rectangle may also be -filled
text similar to Text widget primitive
window allows embeddding of other widgets
Return to table of contents
11.5. How do I redraw a line on a Canvas?
By calling the ->coord method on the item as in the following example:
#!/usr/bin/perl
use Tk;
$m = MainWindow->new;
$c = $m -> Canvas;
$i = $c -> create('line', 0,0 => 50,50 );
$c -> pack;
$b = $m -> Button('-text' => 'extend',
'-command' => sub{push_it($c,$i)},
)->pack;
MainLoop;
sub push_it {
my ($canvas, $line) = @_;
$canvas -> coords($line, 0,0 => 100,100 );
}
Thanks to Christopher Dunn and Harry Bochner <bochner@das.harvard.edu> for
providing this question and answer.
Return to table of contents
11.6. How do I use the Canvas as a geometry manager?
In a call to create a window (or anything) on your Canvas you need to specify its position - this is in part how a Canvas can be used as a geometry manager. e.g.:
my($bittag) = $canvar->create('bitmap',10,10, -bitmap=>'hourglass');
Specifies the x=10, y=10 screen pixel location (from the upper left). Other
possible units are:
tag unit example
pixels 25,50 # i.e. no unit tag at all
m milliimeters 10c,20c
c centimeters 1c,2c
p points (1/72") 35p,70p
There can be a great deal more to it than just units, however. Note the
following question posed and answered by Eric J. Bohm.
Eric J. Bohm <bohm@cs.buffalo.edu> wrote:
!I've got a row of entries packed side by side in a frame.
!These frames are packed on top of each other.
!So, when someone deletes a row, the lower ones bubble
!up automatically. This works just fine and dandy, and let me
!extend my thanks to our brave and energetic pTk team.
!
!The trick here is what widget do I put this in so that
!it will be scrollable when I have too many rows to
!fit on the screen?
[details and complaints]
Following up to my own message here.All right, after several false leads, I spent 3 hours fighting a canvas widget and pounding my head against the canvas.html doc, until I finally understood how to include my entries in a frame in a window in the canvas and get things to scroll nicely.
Turns out that the whole thing isn't all that hard to do once I understood how canvas widgets work.
Not sure if its of general interest, but here's the snippet, which was stolen from the items demo inside the widget_lib and then brutally hacked.
Perhaps a simpler demo would have been easier to use as a guide, but I got there eventually, so my thanks for the widget demo.
#----------------------------------------
my $c = $w_frame->Canvas();
$c->configure(
-height => '300',
-width => '600',
-relief => 'sunken',
-bd => 2,
);
my $w_frame_vscroll = $w_frame->Scrollbar(
-command => ['yview', $c]
);
my $w_frame_hscroll = $w_frame->Scrollbar(
-orient => 'horiz',
-command => ['xview', $c]
);
$c->configure(-xscrollcommand => ['set', $w_frame_hscroll]);
$c->configure(-yscrollcommand => ['set', $w_frame_vscroll]);
$w_frame_hscroll->pack(-side => 'bottom', -fill => 'x');
$w_frame_vscroll->pack(-side => 'right', -fill => 'y');
$c->pack(-expand => 'yes', -fill => 'both',-side=>'top');
my $entryframe=$c->Frame;
my $c_win= create $c 'window','0','0',
-window=>$entryframe,
-anchor=>'nw';
#----------------------------------------Where $c -> configure( -scrollregion => [$top, $left, $right, $bottom]) can be used to size things nicely once you find out how big it'll be.And the widgets you want scrolled should be slaves of $entryframe.
Vastly more robust than anything I had running in the BLT Table.
EJB
Return to table of contents
11.7. How do I get a Canvas to output PostScript(c)?
Many thanks to Tom Oelke <tpo9617@rit.edu> for providing this question, answer & snippet of code:
The following section of code gets the postscript code for the section of canvas that's top-left corner is at $min_x, $min_y, and has a width and height equivalent to the displayed region. This ps code is then piped out to lpr to be printed.
my $ps = $canvas->postscript( '-x' => $min_x,
'-y' => $min_y,
-width => $canv->Width,
-height => $canv->Height);
open (PS, "| lpr"); # customize with -Pname e.g.
print PS $ps;
close (PS);
Whereas you would use something like:
open (PS, ">file.ps"); # to output to a file
print PS $ps;
close (PS);
Return to table of contents
11.8. How do I get a PostScript(c) output of a Canvas w/ widgets?
In general you don't. You can't do it in Tcl/Tk either (if that is any consolation). Nick Ing-Simmons posted an explicit discussion of what is involved:
Subj: RE: Canvases and postscript output On Tue, 28 Nov 95 14:37:09 PST Davis <morry@dsg.tandem.com> writes: ! I have a canvas with text and some entry widgets that I want to create !postscript from. I used the !widget->postscript( -file => 'ld.ps', -colormode => 'gray'); !the file gets created but its empty. Is there some other options I need?
Core Tk cannot write postscript for embedded windows, the best it could do would be to grab a Pixmap of the window as displayed. This is fine if the window is visible, but if it is scrolled off screen or under another application there is no pixmap.Only complete fix is to have a ->postscript method for every possible widget which can render un-mapped widgets. This is non-trivial task.
!Also I have a scrollbar for this canvas and when I scroll the entry widget !actually scroll part way out of the frame the canvas is in. Why does this !happen and can I fix it?
The Entry widgets need to be descendants of the canvas or they just get clipped to their parent.
Return to table of contents
11.9. How do I get the size of a Canvas? After a re-size?
$canvas->cget(-width);
simply returns the size of the canvas when it was created, whereas
$canvas->Width;
will get the answer even after a re-size. Substitute [Hh]eight for
[Ww]idth in the above if that is what you want.
Nick Ing-Simmons points out that if you want to have your Canvas be able to grow to arbitrarily large sizes be sure to specify the -expand or -fill options when you ->pack the Canvas.
Return to table of contents
11.10. How do I bind different actions to different areas of the same Canvas?
KOBAYASI Hiroaki <kobayasi@sowa.is.uec.ac.jp> recently posted an extraordinary little script that addresses this question quite succinctly:
How about this?
## I don't know whether this is a good solution or not.
## but it works under Tk-b9 + perl5.002b1f.
#!/usr/local/bin/perl -w
use Tk;
($c = MainWindow->new->Canvas)->
pack(-fill => 'both', -expand => 1);
# to survive under Tk-b8.
# You don't need paren before pack in b9.
($pop1 = $c->Menu)->command(-label => "FOO");
($pop2 = $c->Menu)->command(-label => "BAR");
$c->create(oval => 0, 0, 100, 100,
-fill => 'black',
-tags => ['popup']);
$c->Tk::bind($c, '<3>', [\&PopupOnlyThis, $pop1]);
$c->bind('popup', '<3>', [\&PopupOnlyThis, $pop2]);
sub PopupOnlyThis {
print "@_\n";
my($c, $pop) = @_;
# to prevent multiple popup.
Tk->break if defined $Tk::popup;
my $e = $c->XEvent;
$pop->Popup($e->X, $e->Y);
# Tk::Menu::Popup sets $Tk::popup.
}
MainLoop;
$Tk::popup = undef; # to kill warning.
__END__
Return to table of contents
Everything in Tk-land is a reference. When defining callbacks take care to pass variables by reference. Callbacks are closures and to ensure a variable gets its current value, as opposed to its value when the callback is defined, pass by reference, e.g.:
$frog = 123;
$b = $mw->Button(
-text => 'Push Me',
-command => [
sub {
my($widget, $frog) = @ARG;
print STDERR "widget=$widget!\n";
print STDERR "frog=$$frog!\n";
}, $mw, \$frog,
],
); # end Button definition
If $frog is not passed by reference the print statement will always output "123" (actually, the print as it exists will print nothing since it's trying to dereference $frog, which presumably is now not a reference). Note that by definition all perl/Tk widgets are already references, since they're simply Perl objects, and that's why you do not have to print $$widget!
A good "reference" for handling references and dereferencing are the perlref(1) and perlobj(1) man pages. A good "reference" for the various data types you will encounter in this kind of perl programming is Tom Christiansen's Perl Data Structures Cookbook which is now available as the perldsc(1) man page.
Also beware the traps that befall perl4 programmers in making the move to perl 5. References for this include the new perltrap(1) man page as well as William Middleton's perl425 trap document at:
http://www.perl.com/perl/all_about/perl425.html
or
http://w4.lns.cornell.edu/~pvhp/ptk/misc/perl425.html
Return to table of contents
12.1. What do the ->, => and :: symbols mean?
The -> is the "infix dereference operator". In other words it is the means by which one calls a sub with a pass by reference (among other things you can do with ->). As stated above most things in calls to perl/Tk routines are passed by reference. The -> is used in perl just as in C or C++. (Most of the widget primitives are elements of the Tk:: "perl class".) A simple example of dereferencing would be:
$x = { def => bar }; # $x is a reference to an anon. hash
print $x->{def},"\n"; # prints ``bar''
Note that in the case of calling perl/Tk subs there
may be more than one way to call by reference. Compare
my($top) = MainWindow->new;
with
my($top) = new MainWindow;
But in general you will be making extensive use of calls like:
$top -> Widge-type;
There is a clear and succint discussion of references, dereferences, and even
closures in
man perlref(1) or see the perl 5 info page at:
http://www.metronet.com/perlinfo/perl5.html
The use of the => operator is quite common in perl/Tk scripts.
Quoting from
man perlop(1):
The => digraph is simply a synonym for the comma operator. It's useful for documenting arguments that come in pairs.You could say that => is used for aesthetic or organizational reasons. Note in the following how hard it is to keep track of whether or not every -option has an argument:
$query -> Button(-in,\$reply,-side,'left',-padx,2m,-pady,
2m,-ipadx,2m,-ipady,1m)->pack(-side,'bottom');
As opposed to:
$query ->Button( -in => \$reply,
-side => 'left',
-padx => 2m,
-pady => 2m,
-ipadx => 2m,
-ipady => 1m
)->pack(-side => 'bottom');
By the way if you wanted the numeric "greater than or equal" you
would use >= not =>.
While the :: symbol can be thought of as similar to the period in a C struct, it is much more akin to the :: class scope operator in C++:
a.b.c; /* something in C */
a::b::c(); // function in C++
$a::b::c; # a scalar in Perl 5
@a::b::c; # a list in Perl 5
%a::b::c; # an associative array or "hash" in Perl 5
&a::b::c; # a function in Perl 5
It is also analogous to the single forward quotation mark in perl 4:
$main'foo; # a $foo scalar in perl 4
$main::foo; # a $foo scalar in Perl 5
For backward compatibility perl 5 allows you to refer to $main'foo
but $main::foo is recommended.
Return to table of contents
12.2. What happened to the ampersands &?
Perl 4 programmers especially may be surprised to find that as of Perl 5.0 the ampersand & may be omitted in a call to a subroutine if the subroutine has been declared before being used. Actually you can even get around the declare before omit ampersand rule by using the subs.pm pragma, or by pre-declaring (without defining) as in a script like:
#!/usr/bin/perl -w
use strict;
use Tk;
sub Mysub; #pre-declare allows calling Mysub()
...Other main/Tk stuff -
including call to Mysub() sans &...
sub Mysub {
...Mysub stuff...
}
Note however that one place the \& reference is
sometimes used in perl/Tk in the setting up a callback for a widget.
Other references are possible: e.g. \$foo is a
reference to the scalar variable $foo (this was true even
under perl 4).
Return to table of contents
12.3. What happened to the quotation marks?
Perl 4 programmers especially may be surprised to find a serious dearth of quotation marks around strings in perl 5 scripts such as in perl/Tk. The "rules have been relaxed" somewhat for the use of quotation marks. Basically it is OK to leave them out if the context of the string in question is unambiguous. However, it never hurts to leave them in and may help readability.
Here is Larry Wall's synopsis of the string situation:
In article <4e49fv$j0u@panix3.panix.com>,
Andy Finkenstadt <genie@panix.com> wrote:
! Back when I was learning perl (after receiving a review copy of
! learning perl, and buying the real perl book, each from ORA),
! I always got bit by when I needed to use "strings" and when
! I could get away with bare_words within braces for associative
! arrays. (Yes, this is under 4.036 if it matters.)
!
! the most typical example would be:
!
! When must I use $assoc{"trailer"} and when can I get away with
! $assoc{trailer}? Similarly, $ENV{CONTENT_LENGTH} versus
! $ENV{"CONTENT_LENGTH"}? Unfortunately sometimes my strings
! end up being numbers in their own right, i.e.: $message{"0"}
! or $msg=0; $message{$msg}. Which is more appropriate,
! which are merely stylistic, and which are stricly perl5
! features now that I'm upgrading most of my installations
! of perl.Perl 4 let you use a "bareword" for a string if it had no other interpretation. It would warn you under -w if you used a word consisting entirely of lower-case characters, since such a word might gain an interpretation someday as a keyword.Perl 5 still works the same way, but with several twists.
The upshot of these rules is that you can write Perl 5 with much less punctuation than Perl 4, yet also with less ambiguity. If you so choose.Larry
Tcl programmers should note that in Perl the single quotation marks '' act much as the curly brace {} enclosure does in Tcl (no escaping special characters $@\ etc.). Whereas the double quotation marks "" allow for substitution of $variables (the rules are a little different between Tcl and Perl however).
Note also that a frequently seen short hand in perl5/Tk scripts is the @list returned by qw():
@list = qw(zoom schwartz bufigliano);
which is equivalent to:
@list = split(' ','zoom schwartz bufigliano');
or more simply:
@list = ('zoom','schwartz','bufigliano');
i.e. the qw/STRING/ @list is not equivalent to the
quotation marks provided by q/STRING/, qq/STRING/,
or qq(STRING)...
There are, ironically enough, situations in perl/Tk where one needs to use quotation marks as in the following by post by <a904209@pluto.tiuk.ti.com>:
Paul Wickman wrote in article <4b4o0fINNlu8@CS.UTK.EDU>: ! ! Why does the following statement work fine: ! !$day->pack(-before => $year, -side => 'left'); ! ! But the below generates the given error: ! !$day->pack(-after => $year, -side => 'left'); ! !Ambiguous use of after => resolved to "after" => at line 191. !
Because there is a sub after in scope, probably imported from Tk via use Tk;.There are two workrounds:
use Tk qw(MainLoop exit ...); # just ones you use
or
$day->pack('-after' => $year, -side => 'left');
Return to table of contents
12.4. Must I use "my" on all my variables?
If you use strict; (as recommended) the answer is "probably". This confines the variables names to your namespace - so your variable does not conflict with one in the module(s) your are using (you are at the least useing Tk;). my does "lexical scoping" on a variable rather than the "dynamic scoping" done by local (like auto variables in C). The difference between these two is that the scope of my $var is confined to the block (sub, if, foreach, etc.) in which it is declared and used, as opposedto local $iable which can propogate to all blocks called by the block in which it is declared. In general the confined scope of my $var means that its use will proceed quicker and more efficiently than local $iable.
If you give a fully qualified variable name such as
$main::var = 1; # No "my" needed
Then no my $var is needed. However, the lexical scoping of
my $var makes it preferable.
If you choose to use my (as recommended) then beware that you should declare a variable my only at the first use (instantiation) of a variable. Consider yet another way to re-write the "Hello World!" script:
#!/usr/local/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
my $label = $main->Label(-text => 'Hello World!');
my $button = $main->Button(-text => 'Quit',
-command => sub{exit});
$label->pack; #no "my" necessary here
$button->pack; #or here
MainLoop;
Considering the finite number of names (in particular the high probability that
a variable named $label or $button was used in one or more of the extensions to
perl that you may be using)
it helps one's programming to use strict; and declare variables
yours alone with my.
James M. Stern points out that redundant my declarations are not simply useless they can be dangerous as in the following script which will not work:
#!/usr/local/bin/perl -w
use strict;
use Tk;
my $main = new MainWindow;
my $label = $main->Label(-text => 'Hello World!');
my $main; #WRONG: this $main overrides previous
my $button = $main->Button(-text => 'Quit', #will now fail
-command => sub{exit});
$label->pack;
$button->pack;
MainLoop;
Return to table of contents
12.5. Is there a way to find out what is in my perl/Tk "PATH"?
Presuming this question is asking for a little more than the answer you get when you type:
ls perl5/lib/Tk/*.pm
there are ways to find out what gets EXPORTED by Tk.pm. Use a script like:
#!/usr/bin/perl
use Tk;
require 'dumpvar.pl';
dumpvar('Tk');
or more succintly at the shell command prompt:
perl -e 'use Tk; require "dumpvar.pl"; dumpvar("Tk");'
The advantage of using dumpvar over ls is that it
gives you a brief summary of all the arguments your widgets want.
Note that the output is many lines and you may wish to pipe through
more or less.
If you wish to determine the Configuration options a given widget accepts (and what the values are at a given point in a script) you may use the ->configure method with no arguments to retrieve the list of lists, as in this example:
#!/usr/bin/perl
use Tk;
my $main = MainWindow -> new;
my $scrl = $main -> Scrollbar('-orient' => 'horizontal');
@scrollconfig = $scrl -> configure;
for (@scrollconfig) {
print "@$_\n";
}
etc.
Such code is useful for development but is probably best left out, commented
out, or switched out of "production line" code.
Return to table of contents
12.6. What is the difference between use and require?
The short answer is that something like:
use Tk;
is equivalent to:
BEGIN { require "Tk.pm"; import Tk; }
Hence the essential difference is that a mere require Tk; does not
achieve the import of function/method names. The significance of
this is that it allows one to call ->Button rather than having
to call the fully qualified ->Tk::Button e.g.. For
further details on this subject see
man perlmod(1) or see Tom Christiansen's document at:
ftp://ftp.perl.com/perl/info/everything_to_know/use_vs_require
Return to table of contents
12.7. How do I change the cursor/color?
Nick Ing-Simmons <nik@tiuk.ti.com> and others posted a series of answers to this type of question. In summary what they said was:
Basically
$mw->configure(-cursor => ... );
Unless you use one of built-in cursors it gets messy.Here copy of what Tk/demos/color_editor does:
#!/usr/local/bin/perl -w
use Tk;
my $mw = MainWindow->new;
$mw->configure(-cursor => ['@' . Tk->findINC('demos/images/cursor.xbm'),
Tk->findINC('demos/images/cursor.mask'),
'red', 'green']);
MainLoop;
That says that argument to -cursor is a list of 4 things:
! I want to remap it for the MainWindow ! and will be using a pixmap.
You won't be using a Pixmap with normal X11. X11 allows *bitmap* with optional mask (another bitmap), and two colours.The optional nature of the mask means that a simple call with a list reference like:
$mw->configure(-cursor => ['watch', 'red', 'blue']);
should work alright.
You may also obtain the value of the default cursor for a widget using something like ->optionGet.
Return to table of contents
The short answer is
$widget -> bell;A slightly longer answer might include a fully functioning script:
#!/usr/bin/perl
use Tk;
$main = MainWindow -> new;
$butn = $main->Button(-text => 'bell')
$butn->configure(-command => sub{ $butn->bell; });
$butn->pack();
MainLoop;
An even longer answer would be a fully functioning script with a callback:
#!/usr/bin/perl
use Tk;
$main = MainWindow -> new;
$but = $main->Button(-text => 'bell',
-command => sub{ringit($main)})->pack;
MainLoop;
sub ringit {
my $m = shift;
$m->bell;
}
Simon Galton <galtons@candu.aecl.ca>
reminds us to be careful in that
some systems remap this [the "console bell"] to anything from a digital sound to a flash on the screen.
Return to table of contents
12.9. How do I determine the version of perl/Tk that I am running?
With an up to date perl installation one may query the local perl setup and all extensions via the command:
perldoc perllocal
For the Tk extension: version numbering has changed recently and determining
the version of perl/Tk that you are running now depends on what version you
are running:
Tk-b10++:
Tk-b10 (and higher) has changed to $Tk::VERSION (rather than
the older "$Tk:Version") to be consistent with other packages.
Hence a short succinct way to tell which version you have installed (that works
with Tk-b11 and Tk400.200) is:
perl -MTk -e 'print $Tk::VERSION."\n"'
Tk-b9.01:
The version numbers as of Tk-b9.01 are stored in the following variables:
Core Tk version : $Tk::version
Tk patchLevel : $Tk::patchLevel
library : $Tk::library
perl/Tk Version : $Tk::Version
At your shell prompt you could say something like the following to determine
you perl/Tk Version:
perl -e 'use Tk; print "$Tk::Version\n";'
The switch to Tk-b9.01 from previous versions included a large number of method
name changes. Nick was kind enough to include a b9names script in
the distribution that assists with the job of updating your older scripts. See
the b9names script for a rather complete discussion of the name
changes. Geoffroy Ville also posted a notice of some of the changes. Here is a
brief (and very incomplete!) summary:
older Tk-b9.01++
packslaves pack('slaves')
packpropagate pack('propagate')
packForget pack('forget')
pack('info')
$w->delete if ($w); $w->destroy if ($w);
Tk-b8(--):
A little script (Tk_module) can tell you and
return the value:
#!/usr/bin/perl
use Tk;
local(*Tk_m) = \$Tk::Tk_module;
print "$Tk_m\n";
Or more succintly say something like the following (at
your shell prompt):
perl -e 'use Tk; print "$Tk::Tk_module\n";'
You can obtain the version of Tk in use with the following
(at your shell prompt):
perl -e 'use Tk; print "$Tk::tk_version\n";'
where this command returned "4.0" when the previous one
(or Tk_module) returned "b8".
All Tk versions:
Don't forget that you can always determine your Perl
version/patchlevel/etc. with:
perl -v
(at the shell prompt - it's actually a little harder to get as much
information from within a #!script.) As of perl 5.002 you can use
perl -V to determine your perl Configuration.
OZAWA Sakuro <ozawa@prince.pe.u-tokyo.ac.jp> points out some ways to do it in a script:
To determine your MakeMaker version number try something like this (5.002):
perl -MExtUtils::MakeMaker -e 'print "$ExtUtils::MakeMaker::VERSION\n";'
or this (5.001m ok):
perl -e 'use ExtUtils::MakeMaker;print"$ExtUtils::MakeMaker::VERSION\n";'
or even this (older perls and MakeMakers):
perl -e 'use ExtUtils::MakeMaker;print"$ExtUtils::MakeMaker::Version\n";'
Please note that thoughout this FAQ document there are references to things
like Tk-b10(++) or Tk-b10++ which roughly translated to
use English; means something like "I think this will work with this
version of Tk and (maybe) higher versions...". You might also see
Tk-b8(--) which means something like "it worked with that old version
and probably worked with prior versions and if you are stuck with an old Tk
version you might have to do it this way...".
Return to table of contents
12.10. How do I call perl from C?
You need to see a recent copy of the perlembed(1) pod page. By "recent" it needs to be up to date with at least perl5.002.
Borrowing from Jon Orwant's preamble to that document:
Do you want to:
http://www.osf.org/~dougm/perl/Devel-embed-*.tar.gz
or
http://www.perl.com/cgi-bin/cpan_mod?module=ExtUtils::embed
Return to table of contents
12.11. How do I call Tcl code from perl/Tk?
Assuming that you have a pressing need to call Tcl from perl/Tk then one "official way" to so would be via the ->send() and the ->Receive() methods.
It is also worth noting that you can still have access to a complete Tcl script from perl via the perl system, or `` (backtick), or even exec mechanisms. Just be careful with I/O waits and return values if you try one of these approaches. Further suggestions may be found in the various perlipc files at:
ftp://ftp.perl.com/perl/info/everything_to_know/
A more satisfactory Tcl/Tk-wish-like behavior can be embedded in
perl by making appropriate modifications to
Dov Grobgeld's perl script that uses
sockets for perl<->wish communication:
#!/usr/local/bin/perl
#####################################################################
# An example of calling wish as a subshell under Perl and
# interactively communicating with it through sockets.
#
# The script is directly based on Gustaf Neumann's perlwafe script.
#
# Dov Grobgeld dov@menora.weizmann.ac.il
# 1993-05-17
#####################################################################
$wishbin = "/usr/local/bin/wish";
die "socketpair unsuccessful: $!!\n" unless socketpair(W0,WISH,1,1,0);
if ($pid=fork) {
select(WISH); $| = 1;
select(STDOUT);
# Create some TCL procedures
print WISH 'proc echo {s} {puts stdout $s; flush stdout}',"\n";
# Create the widgets
print WISH <<TCL;
# This is a comment "inside" wish
frame .f -relief raised -border 1 -bg green
pack append . .f {top fill expand}
button .f.button-pressme -text "Press me" -command {
echo "That's nice."
}
button .f.button-quit -text quit -command {
echo "quit"
}
pack append .f .f.button-pressme {top fill expand} \\
.f.button-quit {top expand}
TCL
# Here is the main loop which receives and sends commands
# to wish.
while (<WISH>) {
chop;
print "Wish sais: <$_>\n";
if (/^quit/) { print WISH "destroy .\n"; last; }
}
wait;
} elsif (defined $pid) {
open(STDOUT, ">&W0");
open(STDIN, ">&W0");
close(W0);
select(STDOUT); $| = 1;
exec "$wishbin --";
} else {
die "fork error: $!\n";
}
Ilya Zakharevich
<ilya@math.ohio-state.edu>
has a "ptcl.h" header file for the construction of tcl bindings from
pTk (there are limitations to this approach). It was posted to the mailing
list archive at:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.11/0057.html
If you absolutely must pass large amounts of pre-parsed data between Tcl and
perl then perhaps you should look into Malcolm Beattie's Tcl/Tk
extensions to Perl instead. Those modules are distrubuted at
CPAN sites. As mentioned above running Tcl/Tk/perl is
incompatible with running perl/Tk.
Return to table of contents
13. What are some of the primary differences between Tcl/Tk and Perl/Tk?
Considering that both interpreters/(compiler) for Tcl and Perl were written in C for original use on Unix computers it is not surprising that there are some similarities between the two languages.
Nevertheless, there are a large number of differences between the Tcl language and the Perl language. One thing to keep in mind is that to build, install, and use Perl/Tk one does not need to have Tcl/Tk on hand at all. Perl/Tk is completely independent of Tcl/Tk.
Tom Christiansen (a definite perl proponent) has put up a web page that elucidates some critical technical differences between Tcl and Perl at:
http://www.perl.com/perl/versus/tcl-discussion.html
Within each language there is Tk - a widget Toolkit. One must be
careful that some of the Tcl/Tk widget names and options have been modified
slightly in the perl/Tk language.
With Tk-b9.01 (and higher) a great many functions (method calls actually)
start with an upper case letter and continue with all lower case letters
(e.g. there is a perl/Tk Entry widget but no entry
widget), and many configuration options are all lower case
(e.g. there is a perl/Tk highlightthickness option
but no highlightThickness option).
Thus if you are having trouble converting a script check your typing.
(there is a script b9names to help). There is also a
tcl2perl script (discussed later).
The html docs that get created during the build of perl/Tk ought to help clarify most any language difference. While the following table does not cover all the differences it is hoped that it will prove useful, especially to those people coming from a primarily Tcl/Tk programming background. These are some of the common Tcl->Perl stumbling points:
what Tcl/Tk Perl/Tk
variable set a 123 $a = 123; or $a = '123';
initialization
re-assignment set b $a $b = $a;
lists/arrays set a {1 2 fred 7.8} @a = (1,2,'fred',7.8);
re-assignment list set b $a @b = @a;
associative set a(Jan) 456.02 %a = ('Jan',456.02,'Feb',534.96);
arrays set a(Feb) 534.96
re-assignment foreach i \ %b = %a;
[array names a] {
set b($i) = $a($i) }
Note on the above examples:
In Tcl the scalar, list, and array variable 'a' will overwrite each
previous assignment.
In Perl $a, @a, %a are all distinct (occupy separate namespaces).
expressions set a [expr $b+$c] $a = $b+$c;
increment incr i $i++; or ++$i;
declare proc plus {a b} { sub plus { my($a,$b) = @_;
subroutines expr $a + $b } $a+$b; }
variable scope local default global default
override w/ "global" override w/ "my" (or "local")
call plus 1 2 &plus(1,2); #or
subroutines plus(1,2); #OK after sub plus
statement sep newline or at ";" ";" required
statement "\" - newline none required
continuation
verbatim strings {} ''
e.g. {a \ lot@ of $stuff} 'a \ lot@ of $stuff'
escaped strings "" ""
e.g. "Who\nWhat\nIdunno" "Who\nWhat\nIdunno"
STDOUT puts "Hello World!" print "Hello World!\n"
puts stdout "Hello!" print STDOUT "Hello!\n"
Note also that Tcl/Tk has a built-in abbreviation completion mechanism that
lets you specify short hand, e.g.
canvas .frame.canvas -yscrollcommand ".frame.scroll set" ; #Tcl/Tk OK canvas .frame.canvas -yscroll ".frame.scroll set" ; #Tcl/Tk also OK $canvas=$main->Canvas(-yscroll => ['set',$scroll]); #ERROR perl/Tk $canvas=$main->Canvas(-yscrollcommand => ['set',$scroll]); #perl/Tk OKYou may get around this with the perl abbrev.pl package in certain circumstances. For example:
require 'abbrev.pl';
%foo = ();
&abbrev(*foo,'-yscrollcommand');
...
$canvas=$main->Canvas($foo{'-yscroll'} => ['set',$scroll]); #perl/Tk OK
In Perl you can emulate the Tcl unknown proc (through the perl
AUTOLOAD mechanism) as follows:
use Shell;
print($p = man(-k => bitmap));
Which is equivalent to what you would get if you typed:
man -k bitmap
From within tclsh or wish. (Thanks to
Ilya Zakharevich
<ilya@math.ohio-state.edu>
for pointing out this feature. ;-)
Return to table of contents
14. How do I install new scripts | modules | extensions?
(Thanks to Ilya Zakharevich <ilya@math.ohio-state.edu> for pointing out that perl code comes in a variety of flavors and some code requires more work than others to install. Hence I have expanded this topic and will refer to three distinct categories here: Scripts Modules and Extensions:)
Other things you do not want to forget when trying to run a perl script include giving yourself permission to do so, e.g.:
chmod u+x newscriptname
You also want to be sure your DISPLAY environment variable is set up
properly when attempting to run a perl/Tk script. You may also need to look at
the xhost(1) or the xauth(1) man pages for setting up
your X-display properly.
If you are still experiencing difficulty check to be sure that extraneous /newsgroup|e-mail|HTML headers|footers|markup//; are not in the file and that you have on hand all that is requireed or useed by the script (if not you may need to install a module - or even a perl4 style lib.pl file).
#!/usr/bin/perl -w
BEGIN { @INC = ("$ENV{'PWD'}",@INC); }
use Tk;
use Foo;
or
#!/usr/bin/perl -w
use lib $ENV{PWD};
use Tk;
use Foo;
Another approach is to set either the PERLLIB or PERL5LIB environment variable
from your shell. This method allows invoking the test script from within a
number of different directories without having to edit a hard coded
use lib or push(@INC,".") kind of statement within the
script. Yet another way to do it is with the -I switch on the
command line like so:
perl -Ipath/to/Foo -e fooscriptname
After a successful test; if you are a system administrator, or have root priveleges, or are modifying your own copy of perl; then copy it to the perl5/Tk directory. Depending on how the module was written it should be possible to use it either with the use Tk; statement itself or with an explicit use Tk::Foo; (for module perl5/Tk/Foo.pm).
perl Makefile.PL
You may now run make on the resultant Makefile - but the
details of this process are module dependent and should be documented in a
README or an INSTALL file. A very standard perl extension
requires 4 (or 5 if making static) standard commands to make and install:
perl Makefile.PL
make
make test
make install
If you have the appropriate CPAN and FTP modules already installed you can
retrieve a module from CPAN and carry out all of the above
steps with a perl one-liner like this:
perl -MCPAN -e 'install "Foo"'
Return to table of contents
15. How do I write new modules?
You might want to start by poking around your perl/Tk build directory. Is there something there that already does what you want? Is there something that is reasonably close - but only requires minor modification?
Next go through the various perl documents - including the FAQ as well as the various relevant man pages: perlmod(1), perlobj(1), perlbot(1), (and please don't forget: perlpod(1)!)
Post your idea to comp.lang.perl.tk and discuss it with others - there might very well be someone working on an approach already. A clear explanation of all the stuff that gets put into a module was posted to the mailing list and can be found in the archive at:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.10/0012.html
Also, be sure to check out a recent version of the
official Module List
that Tim Bunce
<Tim.Bunce@ig.co.uk>
and Andreas Koenig
<a.koenig@franz.ww.TU-Berlin.DE> maintain
and post to comp.lang.perl.announce
periodically. The list is also available at
any CPAN ftp site as well as:
http://www.perl.com/CPAN/modules/00modlist.long.html
ftp://rtfm.mit.edu/pub/usenet/news.answers/perl-faq/module-list
ftp://ftp.demon.co.uk/pub/perl/db/mod/module-list.txt
ftp://ftp.wpi.edu/perl5/Modules/module_list.txt
Finally ready to ship? Small (perl/Tk) modules have been posted
directly to comp.lang.perl.tk. Big
modules may require ftp distribution (see upload info at one of the
CPAN sites) then make your announcement to
comp.lang.perl.tk and possibly to
comp.lang.perl.announce.
Return to table of contents
Composite widgets combine the functions of two or more widget primitives into something that is not quite a stand alone program but is something that may prove very useful for inclusion in your own scripts. A variety of composite widgets have been written and many are still being worked on. Many come bundled with your perl/Tk distribution kit, and some are simply posted to comp.lang.perl.tk. It is quite common to have composite widgets written in perl modules - usually in terms of the Tk widget primitives. Graphical examples of some of the composites discussed here can be seen by GUI browsers at:
http://w4.lns.cornell.edu/~pvhp/ptk/ptkIMG.html
Return to table of contents
16.1. How do I get a Dialog box?
For things like a simple "are you sure?" dialog box you might want to take a look at perl5/Tk/Dialog.pm. This module may be invoked with require Tk::Dialog; etc. - there are much more extensive directions inside the comment fields at the top of the Dialog.pm file itself. The module has a lot of options and has a tutorial driver script in perl5/Tk/demos/dialog. Dialog.pm is also used by the perl5/Tk/demos/widget demo. In particular look at perl5/Tk/demos/widget_lib/dialog1.pl and dialog2.pl for examples of how one makes use of Tk::Dialog. A snippet of a script that uses this module could look like:
require Tk::Dialog;
my $mw = MainWindow->new;
my $D = $mw->Dialog(
-title => 'Are you sure?',
-text => "You have requested rm \*\nAre you sure?",
-default_button => 'No',
-buttons => ['No','yes']
);
my $choice = $D->Show; # use Show for Tk-b9.01
# if using Tk-b8: my $choice = $D->show;
print " you chose $choice \n";
A question concerning configuration of the Subwidgets on the Dialogs
came up recently:
<Greg_Cockerham@avanticorp.com> wrote: ! I want to reconfigure the colors of the Dialog and ! ErrorDialog buttons. How do I do this? ! Thanks in advance. $dialog_widget->configure(-background => 'purple');
Since these two widgets are composites you manage them like any 'ol widget. If the default delegate subwidget(s) aren't to your liking you can always get to individual component widgets of the composite via the ->Subwidget() method.I see these subwidgets:
You can even do things like this:
$error_dialog->Subwidget('error_dialog')->
Subwidget('bitmap')->configure(..);
to "get to" the label widget of the dialog component of the error_dialog widget.....Be sure to also check out the "dialog" demo.
Return to table of contents
16.2. Is there a file selector?
Yes, there may be several eventually...
One distributed with the perl/Tk code kit itself is called FileSelect.pm and was written by Frederick L. Wagner - (based on an original by Klaus Lichtenwalder).
Another module called SelFile.pm was adapted by Alan Louis Scheinine from Wagner's FileSelect.pm. It is available from:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.11/0122.html
or
http://w4.lns.cornell.edu/~pvhp/ptk/etc/SelFile.pm
A module called FileSave.pm allows one to type in a new (non-existant) filename
for "Save as..." type operations. It was posted by Mark Elston on
12 Oct 1995 to the mailing list and is available from:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.10/0093.html
or
http://w4.lns.cornell.edu/~pvhp/ptk/etc/FileSave.pm
A slightly different behaviour is to be had with Brent B. Powers'
FileDialog.pm that was posted to the mailing list on 12 Jan 1996 and
available from:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.12/0201.html
or
http://w4.lns.cornell.edu/~pvhp/ptk/etc/FileDialog.pm
Harry Bochner chimed in with SaveAs.pm. It is available from:
http://w4.lns.cornell.edu/~pvhp/ptk/etc/SaveAs.pm
In general, if there is a feature that you want missing from one of these, or
some behaviour that you would like to see modified then by all means
cp the source code to your area and start hacking ;-)
Return to table of contents
16.3. Is there a color editor?
There is. Please see
perldoc ColorEditor.pm
or run the Tk/demos/color_editor demo script for more
information.
Return to table of contents
It is not quite a "round Scale" but Roy Johnson has written "Dial.pm" for round dial (or speedometer) -like settable widgets. It is available from:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.08/0431.html
or
http://w4.lns.cornell.edu/~pvhp/ptk/etc/Dial.pm
As well as from the Contrib/ sub-directory of your
perl/Tk build directory.
Return to table of contents
16.5. Is there something equivalent to tkerror?
Yes there is. Please see the Tk/ErrorDialog.pm module for further information.
Return to table of contents
There are least two:
http://w4.lns.cornell.edu/~pvhp/ptk/etc/Table.pm.html
ftp://moulon.inra.fr/pub/pTk/
or from a CPAN site in the
authors/id/GUYDX/
directory. You may also browse the perl BLT_Table man page on the web at
http://w4.lns.cornell.edu/~pvhp/ptk/etc/Table.html
Return to table of contents
17. Programming/development tools.
There are a number of tools and methods to help you with your perl/Tk scripting and development. It is worthwhile to note here that the -w switch is recommended as is the use strict; statement near the top of your script/program. If it dies and you still cannot decrypt the error message that these generate take a look though man perldiag(1).
Return to table of contents
17.1 Is there a Tcl/Tk to perl/Tk translator?
Nick Ing-Simmons has written a (rather lengthy) tcl2perl script.
It is distributed with the perl/Tk build kit. Please handle
carefully! (translation: do not expect it to translate arbitrary tcl code
accurately nor even into the most efficient perl/Tk equivalent. Do go over the
converted script with care - and do not forget -w and
use strict;.) Thanks Nick :-)
Return to table of contents
17.2 Is there something equivalent to wish in perl/Tk?
The answer is yes.
The idea of wish is that you read from <STDIN>
and evaluate each statement. The standard way to do this in perl/Tk is to use
the tkpsh script that comes in your perl/Tk build directory.
Another elegant way to get wish like behavior in
perl/Tk is to use rmt which you can find in perl5/Tk/demos
in your perl/Tk distribution.
When you run rmt you already have Tk.pm set up for you so
you can start typing things like $mmm = new MainWindow; etc.
at the rmt: prompt. (This use belies the power of rmt which
is derived from Ousterhout's Tcl/Tk version of rmt [see section 27.2 of
his book]. rmt is capable of "inserting Tk code" into
simultaneously running Tk applications.)
A cruder way to get wish-like behaviour with perl/Tk is to run a
"perl shell" and type in your usual commands, including
use Tk; etc. There is a script distributed with perl called
perlsh which is written quite simply as:
#!/usr/bin/perl
$/ = ''; # set paragraph mode
$SHlinesep = "\n";
while ($SHcmd = <>) {
$/ = $SHlinesep;
eval $SHcmd; print $@ || "\n";
$SHlinesep = $/; $/ = '';
}
You can use this during code development to test out little snippets of code.
It helps to be an accurate typist and the use strict; is optional
here :-)
KOBAYASI Hiroaki has a more sophisticated wish like perl/Tk "shell" that is called EVA. It is available from:
ftp://ftp.sowa.is.uec.ac.jp/pub/Lang/perl5/Tk/eva-*.tar.gz
Return to table of contents
17.3. Is there a debugger specifically for perl/Tk?
Not for the latest version - but the -w switch and use strict; are always helpful with debugging as they provide informative error messages.
You can, of course, run under the standard perl debugger using the -d switch like so:
perl -d myscript
But it is recommended that you set you breakpoints carefully since just the
calls to ManWindow->new require many steps.
(Older information): Gurusamy Sarathy <gsar@engin.umich.edu> had built a PERL5DB file called Tkperldb (which despite the name is for pTk not Tk/perl). One must install an early de-bugger then apply a patch to bring the debugger up to date. The early debugger kit was available from:
ftp://ftp.perl.com/pub/perl/ext/TK/Tkperldb-*.tar.gz
And Gurusamy Sarathy notes that the patch to bring the debugger up to date is
available at:
You need a post 5.001m perl that has support for debugging closures. Or you can simply apply: http://www-personal.umich.edu/~gsar/perl5.001m-bugs.patch to 5.001m. (5.002beta includes all the fixes in the above patch).Note that a perl debugger may be invoked within your script with a line like:
$ENV{'PERL5DB'} = 'BEGIN { require Tkperldb }';
See
man perldebug(1) for more help.
Keep in mind that you are programming in perl after all. The perl debug line mode is available to you through executing the following from your shell:
perl -de 0
Whereupon you must enter all the lines of a script including
use Tk;. (Fancier file reads & evals are
possible - but if you are getting that sophisticated why not
create your own custom PERL5DB file?)
When using perl -dwe 0 beware of the emacs like
line editing under this debugger, and
be forewarned that as soon as you type in the MainLoop;
statement perl will no longer read from <STDIN>.
Ilya Zakharevich <ilya@math.ohio-state.edu> points out that very recent perldb versions will allow for simultaneous X and STDIN reads. He also points out:
Note that you may use
sub myLoop {
if (defined &DB::DB) {
while (1) { # MainWindow->Count
Tk::DoOneEvent(0);
}
} else {
MainLoop;
}
}
(and I hope the analogous provision will be in MainLoop in
tk-b9 - hi, Nick ;-)
Return to table of contents
17.4. Is there a GUI builder in perl/Tk?
Work has reputedly (January 1996) started on porting a Tcl/Tk GUI builder known as SpecTcl for use with perl/Tk. For the Tcl/Tk SpecTcl kit see:
ftp://ftp.sunlabs.com/pub/tcl/SpecTcl-*.tar.[gz|Z]
and address questions about SpecTcl to
<spectcl@tcl.eng.sun.com>.
In <news:ANDREAS.96Mar24234521@marvin.berlin.de> Andreas Koschinsky <marvin@logware.de> announced a perl script for use with SpecTcl that has some interesting capabilies:
24 Mar 1996 22:45:21 GMTThe URL for ui2perl should be something like:
... So i wrote a perl-script that can convert project-file (.ui-files) which spectcl writes. The script reads the .ui-file and generates an equivalent perl-module.
ftp://susan.logware.de/pub/incoming/ui2perl*.tar.gz
Somewhat more removed from SpecTcl there is also SWIG.
Return to table of contents
18. Processes & Inter-Process Communication under Perl/Tk.
Inter-Process Communication (IPC) is the subject of spawning and controlling other programs or "processes" from within perl (sometimes using sockets to do so). The subject is briefly discussed in the perlipc(1) man page, and was addressed towards the end of Chapter 6 of The Camel. The subject is also discussed in the perl FAQ and at Tom Christiansen's ftp site (in the various perlipc* files) at:
ftp://ftp.perl.com/perl/info/everything_to_know/ 199.45.129.30
as well as the web site at:
http://www.perl.com/perl/everything_to_know/ipc/index.html
In addition to the usual perl IPC routines Tk allows (at least) three more
special functions: fileevent (for handling I/O events),
send (for inter-widget communication), and
after (for time control like a sleep expressly for
widgets). Remember:
If a packet hits a pocket on a socket on a port,
And the bus is interrupted as a very last resort,
And the address of the memory makes your floppy disk abort,
Then the socket packet pocket has an error to report!
-Ken Burchill(?)
Return to table of contents
18.1. How does one get Perl/Tk to act on events that are not coming from X?
On 22 Nov 1995 (Yaniv Bargury) bargury@milcse.cig.mot.com wrote:
I need to write a GUI monitor, that displays the status and controls a set of processes running in the background. The idea is to have the GUI application start a few child processes, command the children through pipes from the GUI to the children, and display the children status coming on pipes from the children to the GUI in real time.To which Nick Ing-Simmons <nik@tiuk.ti.com> replied:The GUI must not be busy waiting, because the CPU resources are limited. This excludes using the Tk_DoWhenIdle as explained in the manual.
The usual way to do this is to for the GUI process to have one select() in its main loop. That select() should wait for X events or input from the pipes leading from the children.
How do you do this?
fileevent - it is the hook into the select() in the mainloop.
In addition Avi Deitcher <avi@morgan.com> replied with:
I wrote something similar to effectively do a tail -f on multiple hosts, displaying the result on separate text widgets. Do the following:
parent
child
child
child
..
with a one-way pipe from each child to the parent. Set up the following:
$main->fileevent(FILEHANDLE,status,subroutine);
for each pipe that you have. This will cause pTk to monitor the FILEHANDLE and call 'subroutine' when an event happens on that handle. In this case: FILEHANDLE = pipename status = 'readable' or 'writable' or 'exception' and subroutine = any subroutine that you want.
To provide a concrete example of fileevent usage Stephen O. Lidie wrote a wonderful little GUI tail monitor he calls tktail:
#!/usr/local/bin/perl -w
#
# tktail pathname
use English;
use Tk;
open(H, "tail -f -n 25 $ARGV[0]|") or die "Nope: $OS_ERROR";
$mw = MainWindow->new;
$t = $mw->Text(-width => 80, -height => 25, -wrap => 'none');
$t->pack(-expand => 1);
$mw->fileevent(H, 'readable', [\&fill_text_widget, $t]);
MainLoop;
sub fill_text_widget {
my($widget) = @ARG;
$ARG = <H>;
$widget->insert('end', $ARG);
$widget->yview('end');
} # end fill_text_widget
An example of how one might use such a script would be to create and monitor a
file foo like so:
echo Hello from foo! > foo
tktail foo &
echo \"A ship then new they built for him/of mithril and of elven glass\" --Bilbo \
>> foo
Return to table of contents
18.2. Is there a send and do I need xauth?
There is a Tk::send, but to use it own must write one's own version of Tk::receive. An example of this may be found in the rmt program distributed with perl/Tk. Note that as of Tk-b12 (including the released version Tk400.200) the script that receives from a Tk::send must run with taint chcecking turned on (i.e. with the -T switch thrown) and it must untaint all commands received from the other process.
The Tk::send <-> Tk::receive process will work under xhost + authority. The security this affords comes from the fact that anyone who would want to exploit it would have to know how to write a Tk::receive custom tailored to your application (in addition to all the other protocol hacking).
Please note that while you may not need xauth authorization it is nevertheless always a good idea.
Return to table of contents
18.3. How can I do animations using after?
There is a "toggling button" demo script supplied with Tk called after_demo that makes effective use of after().
Terry Greenlaw <terry@encompass.is.net> of Encompass Technologies posted a character cell animator for the really bored. Here it is in a slightly modified form that allows string input from the command line (note too the recursive call that doesn't sop up system memory):
#!/usr/bin/perl
=head1 NAME
From: z50816@mip.lasc.lockheed.com "Terry Greenlaw" Thu Feb 1 12:02:24 EST 1996
To: ptk@guest.WPI.EDU
Subj: A code sample for the REALLY bored
For everyone with a case of Browser envy after using Microsoft's Internet
Explorer, here's a perl/tk script only slightly more useful than a script
to do <BLINK>. Don't know why I wrote it. Don't know why you'd run it.
Maybe if you were writing a ticker tape application. Or had a weird thing
for Times Square. Anyway....
tog
Terry Greenlaw (on-site @ Lockheed Martin) Encompass Technologies
z50816@mip.lasc.lockheed.com terry@encompass.is.net
##################################################################
=cut
#!/usr/bin/perl
#use strict;
use Tk;
$message=join(' ',@ARGV,'');
if (!$message) {
$message="THIS IS A VERY LONG SCROLLING MESSAGE... ";
$topmssg="This is the top of the screen";
$botmssg="This is the bottom of the screen";
}
else {
$topmssg=$message;
$botmssg=$message;
}
$top = MainWindow->new;
$l1 = $top->Label(-fg => 'White', -text => $topmssg);
$l1->pack(-fill => 'both', -expand => 1 );
$m1 = $top->Label(-fg=>'Red', -bg=>'black',
-textvariable => \$message,
-width => 15
);
$m1->pack();
$m2 = $top->Label(-wrap=>1,
-fg=>'Green', -bg=>'black',
-textvariable => \$message2,
-width=>1, -height=>8
);
$m2->pack(-anchor=>'w');
$l2 = $top->Label(-fg => 'White', -text => $botmssg);
$l2->pack(-fill => 'both', -expand => 1 );
after(100, \&scroll_it);
$top->MainLoop;
sub scroll_it {
$message =~ /(.)(.*)/;
$message="$2$1";
($message2 = $message) =~ s/ / /g;
after(100, \&scroll_it);
}
__END__
(Please note that a script like this is now distributed as "TickerTape"
in your Tk*/Contrib/ directory.)
Return to table of contents
18.4. How do I update widgets while waiting for other processes to complete?
The short answer is either
$widget -> update;
or
$widget -> DoOneEvent;
Here is a script that makes use of the first of these methods. Note that
instead of actually doing something useful the "long running process" is
simply a call to the perl sleep() function for illustrative
purposes:
#!/usr/bin/perl -w
use Tk;
my $m = MainWindow->new();
my $l = $m -> Listbox();
$l -> bind('<Double-1>' => sub{sleepy($l)} );
my @nuts = qw(Almond Brazil Chestnut Doughnut Elmnut Filbert);
for (@nuts) { $l -> insert('end',$_); }
$l -> pack;
MainLoop;
sub sleepy {
my $widget = shift;
print "before 1st sleep \n";
sleep(10);
print "after 1st sleep before delete \n";
$widget -> delete('active');
$widget -> update; # try [un]*commenting this
print "after delete before 2nd sleep \n";
sleep(10);
print "after 2nd sleep \n";
}
__END__
Return to table of contents
18.5. How do you fork on System V (HP)?
Kraegeloh Martin <mkr@dm-server.cv.com> originally asked:
! Subj: signal handling difference on HP vs. SUN
!
! the following code will fork an xterm with vi in it, and it
! will refuse to do so while the first xterm is still running.
! works fine on my sun.
! On HP however, the second time an xterm is started, NO handler
! is called when the child dies.
!
! the code:
! ===================== 8< ===============================
! $SIG{CHLD}=\&w;
!
! sub w{
! $pid=wait;
! print STDERR "died: $pid\n";
! if ( $have == $pid ) { $have = 0; }
! }
To which a part of Nick Ing-Simmons'
response was:
I suspect HPUX is SysV-ish not BSD or POSIX. So every time a signal fires, it removes the handler - you need to reset it in the handler:
sub w{
$SIG{CHLD}=\&w;
$pid=wait;
print STDERR "died: $pid\n";
if ( $have == $pid ) { $have = 0; }
}
Whether you reset it before/after the wait may be very important ...
Then Bjarne Steinsbo <bjarne@hsr.no> followed up with:
That's not the whole story... Another problem is that SIGCLD interrupts the read system call on SysV-ish (I like that word! :-) systems. This means that you have to test why "" fails, and act accodingly. A program that works on both Sun and HP is:
$SIG{CHLD}=\&w;
while(1){
$_ = ;
$! = 0, next if $! =~ /Interrupted/;
last if $! or !defined $_;
if($have){
print STDERR "child still alive\n";
}
else{
if(($pid=fork()) != 0){
$have=$pid;
print STDERR "forked $pid\n";
}
else {
exec("xterm -e vi")
}
}
}
sub w{
$pid=wait;
print STDERR "died: $pid\n";
if ( $have == $pid ) { $have = 0; }
$SIG{CHLD}=\&w;
}
Return to table of contents
19. How do I "clear the screen"?
What screen are you trying to clear?
If you are trying to clear a tty (e.g. xterm) screen then try either of the following within your script:
system "clear";
or
print `clear`;
(where the choice between these two depends on the rest of the script: the
first is fast - but proceeds via fork and may not occur at exactly
the time that you want it to in the script). David and Rachel Weintraub <davidw@cnj.digex.net> recommend using the old termcap.pl p4 library. You might also consider the perl 5 equivalents: Term.pm (especially the Term::Control module), Curses.pm, Perlmenu.pm, PV.
Returning to X-windows and perl/Tk: if you are trying to eliminate a TopLevel or a MainWindow then try:
$main -> destroy;
If you would rather not destroy then try:
$main->withdraw; # remove
$main->deiconify; # put back
If $w is a sub-window (sub-widget) then
$w->pack('forget'); # remove if packed (newer Tk-b9.01++)
$w->packForget; # remove if packed (older versions)
$w->pack(...); # put back
There are also ways to call low level C-ish versions:
$w->UnmapWindow;
but that is for special purposes only....
If you are trying to erase an $item on a Canvas then try:
delete($item);
(Thanks to the post by <a904209@pluto.tiuk.ti.com> which extended this answer considerably.)
Return to table of contents
20. Is there a way to have an X application draw inside a perl/Tk window?
(This question was posed by Andrew Allen March 19 1997):
No not yet. But according to Nick Ing-Simmons:
If app. can take XID of window to draw on it should be doable now, but if Tk has to pro-actively watch for creation of app's 'top level', and "capture" it is more tricky.
Return to table of contents
21. Is there a version for Microsoft Windows(tm)?
Yes. Tk402.000 is in alpha release at this time (Spring 1997) and builds with perl 5.004, nmake, and Visual C++ on at least Windows NT.
Return to table of contents
22. Are there any international font packages for perl/Tk?
In principle you may specify the -font configuration option on all your Button, Entry, Label, Message, etc. widgets. In addition to the Unix programs xfontsel and xlsfonts you may find xset useful for determining and/or specifying fonts - especially international ones.
KOBAYASI Hiroaki <kobayasi@sowa.is.uec.ac.jp> has converted the Tcl/Tk "japanization" by <nisinaka@sra.co.jp> so that it may be used with perl/Tk. It is presently available (the current README file is in Japanese) from the following ftp site:
ftp://ftp.sowa.is.uec.ac.jp/pub/Lang/perl5/Tk/
From the author's own description:
Currently, the "japanization patch for perl/Tk" enables:
[1] To show kanji & ASCII (by choosen kanji-font) in every widget.
[2] To edit kanji (double width of ASCII) correctly in Text & Entry.
[3] To support of Kanji Input method. (tkKinput.c)
[4] Automatic kanji-code-detection & conversion with 'insert/get'.
Supports: "JIS(Japanese Industrial Standard)", "MS-KANJI", "EUC".
& the patch lacks:
[5] by manual Kanji-code conversion. (JIS <=> MS-KANJI <=> EUC)
[6] 'Good' interface to specify kanji-code used in internal. (tkWStr.c)
[7] Documentation in English about [1-6].
# but, since interface-change is suspected in near future,
# documenting them is ...
I thought that[5-7] was not enough for world-people, but already worth
for natives. So I announced it on "fj.lang.perl".
Return to table of contents
23. Are there any other ways to create event based interfaces from perl?
Yes. A short list would have to mention these for X:
The Perl 5 Module List has a listing of User Interfaces (Character and Graphical).
There is also Malcolm Beattie's Tkperl (which is largely incompatible with perl/Tk).Further information on X interfaces to Perl is provided in the perl FAQ.
For primarily graphics (with some user interface programming) there is also an OpenGL Perl Module of particular interest to anyone with either OpenGL or the MesaGL library. This package allows for compact perl VRML scripting. If you would like to see the OpenGL network X demonstration go to:
http://www.arc.ab.ca/vr/opengl/examples/
(to run that demo one needs only a forms capable web browser and a local
X-server, hence running Lynx on Windows 95 with eXodus is perfectly OK.)
If you would like to see the OpenGL netscape plugin go to:
http://www.arc.ab.ca/vr/opengl/plugin.html
For perl generation of images see the question in this FAQ on graphics modules.
The X window system is not the only means of doing event based user interface programming in perl. There is, for example, William Setzer's Curses modules for perl 5 too.
For Active X scripting on Windows try the PerlScript package from
http://www.activeware.com/
which will work with Internet Explorer, Internet Information Server, as well as the wscript command line interface.
Return to table of contents
24. Where can I get more information on graphics (modules|scripts)?
To generate server side push animation in perl please see the perl cgi FAQ. To generate GIF89a loops from a collection of stills visit the Gifloop page at
http://www.homecom.com/gifanim.htmlFor other animation from perl see the OpenGL module listed below (it does 3D VRML animation).
There are several graphics modules in perl already available - with several more still under development. Among them:
http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html
http://www.fi.infn.it/pub/perl/GIF/
http://www.arc.ab.ca/vr/opengl/
http://www.aao.gov.au/local/www/kgb/pgperl.html
A pgperl/tk script might look like this:
#!/usr/bin/perl
use PGPLOT;
use Tk;
open(IMG,"test.img"); # Read 128x128 image from binary file
read(IMG, $img, 4*128*128); # data - list of 4 byte float [C type]
close(IMG); # stored as perl string.
pgbegin(0,'test.gif/gif',1,1);
pggray($img,128,128,1,128,1,128,1,0,*tr); # pg-Plot it
my $main = new MainWindow;
$main ->Label(-text => 'Main')->pack;
$main -> Photo('IMG', -file => "test.gif");
my $l = $main->Label('-image' => 'IMG')->pack;
$main->Button(-text => 'close',
-command => sub{destroy $main}
)->pack(-side => 'left');
$main->Button(-text => 'exit',
-command => [sub{exit}]
)->pack(-side => 'right');
MainLoop; # pg-tk plot it
http://www.aao.gov.au/local/www/kgb/perldl/
perldl-request@jach.hawaii.edu
http://www.rosat.mpe-garching.mpg.de/mailing-lists/perldl/
Another tip: it is quite useful to have the
PBMPlus/NetPBM set of graphics file
interconversion programs if you will be dealing with many
graphics file
formats. There is a Sunsite web server with many graphics utilities
including netpbm at:
http://sunsite.unc.edu/pub/Linux/apps/graphics/convert/INDEX.short.html
(Note there are linux binaries as well as source code kits there - also at
sunsite mirrors.)
You might also be interested in some of the
graphics file format
specifications.
Other programming tools/utilities are of help with graphics. The X11 release contains many such tools. There is also The GIMP. Consider also the ImageMagick program.
Return to table of contents
25. Are there any major applications written in perl/Tk?
Yes. In fact, there are some interesting perl/Tk applications already available from:
program description pfm perl file manager - cute iconic front to emacs ptknews a GUI perl newsreader - a work in progress. tkpsh perl/Tk equivalent of the Tcl/Tk wish shell. toyedit a Text widget editor.The following programs may be found either in your demos directory (consult the README file there for fuller descriptions) or in your perl/bin install directory:
program description
browse Simple file browser front end for emacs.
color_editor Front end to Tk::ColorEditor
allows RGB, CMY, and HSV color cube manipulation
(based on tcolor.tcl).
ixset GUI front end to xset - for terminal settings.
pgs Perl front end to Ghostscript (viewing PostScript(c) files).
rmt perl/Tk
"development shell/remote control application"
You can launch or talk to other perl/Tk apps with rmt.
rolodex Like the Tcl/Tk app of the same name.
Requires editing for personal use.
timer Stopwatch-like seconds timer.
tkpod The perl gui pod viewer (like xman).
tkweb The perl "Rough and Ready" web browser.
*Peter Prymmer recently posted a means by which one can integrate any or all of
these GUI applications into one's own X-window environment. Here for terse
illustration is the basic idea behind using an X11R6.1 .mwmrc.m4
resource file for making a Menu (make sure the applications are in your PATH
or specify a full path to each one as needed):
Menu Perl
{
"Perl" f.title
"editor" f.exec "toy_edit &"
"tkemacs" f.exec "browse &"
"manual" f.exec "tkpod perl.pod &"
"the web" f.exec "tkweb http://www.perl.com/perl/ &"
"news" f.exec "ptknews comp.lang.perl.tk &"
"pgs" f.exec "pgs &"
"stop watch" f.exec "timer &"
}
# We bind it so that left mouse button when pressed while
# over the root or background pops up with this Perl menu:
Buttons DefaultButtonBindings
{
<Btn1Down> root f.menu Commands
# etc.
}
Buttons ExplicitButtonBindings
{
<Btn1Down> root f.menu Commands
# etc.
}
Return to table of contents
26. What is the history of pTk and perl/Tk?
This list is only slowly coming together. Please forgive any absences.
NOTE This project is unrelated to the one which is adding usersubs to perl4 to get access to Tk via Tcl. Often, postings on comp.lang.perl just say "tkperl" without saying which one is meant. They are two totally different kettles of fish. --Malcolm (Beattie)
I have a re-port of ext/Tk nearly ready for alpha. It builds its own "pTk" library from sources semi-automatically derived from Tk3.6. There is no Tcl library at all. Would anyone like to assist me in testing it?
Return to table of contents
27. What can we expect the future to hold?
With the production release of Tk400.202 and the alpha release of Tk402.000 the future of this code looks quite bright. (Hopefully the FAQ maintainer will manage to keep up :-).
Return to table of contents
28. How do I obtain the latest version of this FAQ?
Plaintext (whole):
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.txt
Plaintext (multi-part):
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ0.txt
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ1.txt
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ2.txt
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ3.txt
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ4.txt
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ5.txt
or gzipped PostScript(c) (about 60 US 8.5"x11" pages):
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.US.ps.gz
or gzipped PostScript(c) (about 60 A4 pages):
http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.A4.ps.gz
Return to table of contents
29. Acknowledgements & maintainer.
The Perl/Tk extension to the Perl programming language is copyrighted by its author Nick Ing-Simmons <nik@tiuk.ti.com> whose Tk400.202/COPYING file reads as follows:
Copyright (c) 1995-1996 Nick Ing-Simmons. All rights reserved. This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself, with the exception of the files in the pTk sub-directory which have separate terms derived from those of the orignal Tk4.0 sources and/or Tix. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. See pTk/license.terms for details of this Tk license, and pTk/Tix.license for the Tix license.Especial thanks to:
In addition, this FAQ has benefitted from the contributions of many people
all over the net to whom I am quite grateful.
Return to table of contents