dwww Home | Manual pages | Find package

UserGuide(3pm)        User Contributed Perl Documentation        UserGuide(3pm)

NAME
       Tk::UserGuide - Writing Tk applications in Perl 5

DESCRIPTION
       This document is for beginners.  It assumes you know some Perl, and have
       it and Tk running.  If you are not currently reading this document
       courtesy of the widget demonstration program, please be sure to run
       widget, as it will show you the various widget types supported by Tk and
       how to use them. widget should be installed in your default path, so
       type widget at a command prompt.

       Here are links to other novice tutorials:

       <http://www.lehigh.edu/~sol0/ptk/tpj1.html>
       <http://www.lehigh.edu/~sol0/ptk/perlmonth01/pm1.html>

       Mastering Perl/Tk is the definitive book on Perl/Tk:

       <http://www.oreilly.com/catalog/mastperltk>

Some Background
       Tk GUI programming is event-driven.  (This may already be familiar to
       you.)  In event-driven programs, the main GUI loop is outside of the
       user program and inside the GUI library.  This loop - initiated by
       calling MainLoop - watches all events of interest and activates the
       correct handler procedures to handle these events.  Some of these
       handler procedures may be user-supplied; others will be part of the
       library.

       For a programmer, this means that you're not watching what is happening;
       instead, you are requested by the toolkit to perform actions whenever
       necessary.  So, you're not watching for 'raise window / close window /
       redraw window' requests, but you tell the toolkit which routine will
       handle such cases, and the toolkit will call the procedures when
       required. These procedures are known as callbacks, and some of them you
       write yourself.

First Requirements
       Perl programs that use Tk need to include "use Tk".  A program should
       also use "use strict" and the -w switch to ensure the program is working
       without common errors.

       Any Perl/Tk application starts by creating the Tk MainWindow.  You then
       create items inside the MainWindow, and/or create new windows called
       Toplevels that also contain child items, before starting the MainLoop,
       which is the last logical statment in your program. You can also create
       more items and windows while you're running, using callbacks.  Items are
       only shown on the display after they have been arranged by a geometry
       manager like pack; more information on this later.  MainLoop starts the
       GUI and handle all events.  That's all there is to it!  A trivial one-
       window example is shown below:

           #!/usr/bin/perl -w
           use Tk;
           use strict;

           my $mw = MainWindow->new;
           $mw->Label(-text => 'Hello, world!')->pack;
           $mw->Button(
               -text    => 'Quit',
               -command => sub { exit },
           )->pack;
           MainLoop;

       Please run this example.  It shows you two widget types, a Label and a
       Button, and how they are packed. When clicked, the Button widget invokes
       the callback specified by the "-command" option.  Finally, note the
       typical Tk style using "-option" => "value" pairs.

Widget creation
       Tk windows and widgets are hierarchical, i.e. one window includes one or
       more other windows.  You create the first Tk window using
       "MainWindow->new".  This returns a window handle, assigned to $mw in the
       example above.  Keep track of the main handle, commonly called a widget
       reference.

       You can use any Tk handle to create child widgets within the window (or
       widget).  This is done by calling the Tk constructor method on the
       variable.  In the example above, the "Label" method called from $mw
       creates a Label widget inside the MainWindow.  In the constructor call,
       you can specify various options; you can later add or change options for
       any widget using the configure method, which takes the same parameters
       as the constructor.  The one exception to the hierarchical structure is
       the Toplevel constructor, which creates a new outermost window.

       After you create any widget (other than the MainWindow or Toplevels, you
       must render it by calling pack.  (This is not entirely true; more
       later)).  If you do not need to refer to the widget after construction
       and packing, call pack off the constructor results, as shown for the
       Label and Button in the example above.  Note that the result of the
       compound call is the result of pack, which is a valid Tk handle.

       Windows and widgets are deleted by calling destroy on them; this will
       delete and un-draw the widget and all its children.

Standard Tk widgets
       Here is an itemize of the standard Tk widget set.

       Button
       Canvas
       Checkbutton
       Entry
       Frame
       Label
       Labelframe
       Listbox
       Menu
       Menubutton
       Message
       Panedwindow
       Radiobutton
       Scale
       Scrollbar
       Spinbox
       Text
       Toplevel

       Perl/Tk  provides  an equal number of new widgets, above and beyond this
       core set.

       Adjuster
       Balloon
       BrowseEntry
       ColorEditor
       Dialog
       DialogBox
       DirTree
       ErrorDialog
       FBox
       FileSelect
       HList
       LabEntry
       LabFrame
       NoteBook
       Optionmenu
       Pane
       ProgressBar
       ROText
       Table
       TextUndo
       Tiler
       TList
       Tree

Variables and callback routines
       Most graphical interfaces are used  to  set  up  a  set  of  values  and
       conditions,  and then perform the appropriate action.  The Tk toolkit is
       different from your average text-based prompting or menu  driven  system
       in  that  you  do not collect settings yourself, and decide on an action
       based on an input code; instead, you leave these values to your  toolkit
       and only get them when the action is performed.

       So, where a traditional text-based system would look like this:

           #!/usr/bin/perl -w
           use strict;

           print "Please type a font name\n";
           my $font = <>; chomp $font;
           # Validate font

           print "Please type a file name\n";
           my $filename = <>; chomp $filename;
           # Validate filename

           print "Type <1> to fax, <2> to print\n";
           my $option = <>; chomp $option;
           if ($option eq 1) {
               print "Faxing $filename in font $font\n";
           } elsif ($option eq 2) {
               print "Now sending $filename to printer in font $font\n";
           }

       The  slightly larger example below shows how to do this in Tk.  Note the
       use of callbacks.  Note, also, that  Tk  handles  the  values,  and  the
       subroutine  uses the method get to get at the values.  If a user changes
       his mind and wants to change  the  font  again,  the  application  never
       notices; it's all handled by Tk.

           #!/usr/bin/perl -w
           use Tk;
           use strict;

           my $mw = MainWindow->new;

           $mw->Label(-text => 'File Name')->pack;
           my $filename = $mw->Entry(-width => 20);
           $filename->pack;

           $mw->Label(-text => 'Font Name')->pack;
           my $font = $mw->Entry(-width => 10);
           $font->pack;

           $mw->Button(
               -text => 'Fax',
               -command => sub{do_fax($filename, $font)}
           )->pack;

           $mw->Button(
               -text => 'Print',
               -command => sub{do_print($filename, $font)}
           )->pack;

           MainLoop;

           sub do_fax {
               my ($file, $font) = @_;
               my $file_val = $file->get;
               my $font_val = $font->get;
               print "Now faxing $file_val in font $font_val\n";
           }

           sub do_print {
               my ($file, $font) = @_;
               my $file_val = $file->get;
               my $font_val = $font->get;
               print "Sending file $file_val to printer in font $font_val\n";
           }

The packer - grouping with Frame widgets
       In  the  examples  above, you must have noticed the pack calls.  This is
       one of the more complicated parts of Tk.  The basic  idea  is  that  any
       window  or widget should be subject to a Tk geometry manager; the packer
       is one of the placement managers, and grid is another.

       The actions of the packer are rather simple: when applied to  a  widget,
       the  packer  positions  that widget on the indicated position within the
       remaining space in its parent.  By default, the position is on top; this
       means the next items will be put below.  You can also specify the  left,
       right, or bottom positions.  Specify position using -side => 'right'.

       Additional  packing  parameters  specify the behavior of the widget when
       there is some space left in  the  Frame  or  when  the  window  size  is
       increased.   If  widgets  should maintain a fixed size, specify nothing;
       this is the default.  For widgets that you want to fill up  the  current
       horizontal  and/or vertical space, specify -fill => 'x', 'y', or 'both';
       for widgets that should grow, specify -expand =>  1.   These  parameters
       are not shown in the example below; see the widget demonstration.

       If  you  want  to group some items within a window that have a different
       packing order than others, you can include them in a Frame.  This  is  a
       do-nothing window type that is meant for packing or filling (and to play
       games with borders and colors).

       The example below shows the use of pack and Frames:

           #!/usr/bin/perl -w
           use Tk;
           use strict;

           # Take top and the bottom - now implicit top is in the middle
           my $mw = MainWindow->new;
           $mw->title( 'The MainWindow' );
           $mw->Label(-text => 'At the top (default)')->pack;
           $mw->Label(-text => 'At the bottom')->pack(-side => 'bottom');
           $mw->Label(-text => 'The middle remains')->pack;

           # Since left and right are taken, bottom will not work...
           my $top1 = $mw->Toplevel;
           $top1->title( 'Toplevel 1' );
           $top1->Label(-text => 'Left')->pack(-side => 'left');
           $top1->Label(-text => 'Right')->pack(-side => 'right');
           $top1->Label(-text => '?Bottom?')->pack(-side => 'bottom');

           # But when you use Frames, things work quite alright
           my $top2 = $mw->Toplevel;
           $top2->title( 'Toplevel 2' );
           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;

More than one window
       Most  real  applications require more than one window.  As you just saw,
       you can create more outermost windows by using a Toplevel widget.   Each
       window  is independent; destroying a Toplevel window does not affect the
       others as long as they are not a child of the closed Toplevel.  However,
       exiting the MainWindow will destroy all remaining Toplevel  widgets  and
       end  the  application.   The  example below shows a trivial three-window
       application:

           #!/usr/bin/perl -w
           use Tk;
           use strict;

           my $mw = MainWindow->new;
           fill_window($mw, 'Main');
           my $top1 = $mw->Toplevel;
           fill_window($top1, 'First top-level');
           my $top2 = $mw->Toplevel;
           fill_window($top2, 'Second top-level');
           MainLoop;

           sub fill_window {
               my ($window, $header) = @_;
               $window->Label(-text => $header)->pack;
               $window->Button(
                   -text    => 'close',
                   -command => [$window => 'destroy']
               )->pack(-side => 'left');
               $window->Button(
                   -text    => 'exit',
                   -command => [$mw => 'destroy']
               )->pack(-side => 'right');
           }

More callbacks
       So far, all callback routines shown called a user  procedure.   You  can
       also  have  a callback routine call another Tk routine.  This is the way
       that scroll bars are implemented: scroll-bars can call a Tk  item  or  a
       user  procedure,  whenever their position has changed.  The Tk item that
       has a scrollbar attached calls the scrollbar when its size or offset has
       changed.  In this way, the items  are  linked.   You  can  still  ask  a
       scrollbar's position, or set it by hand - but the defaults will be taken
       care of.

       The  example  below  shows  a  Listbox  with  a  scroll bar.  Moving the
       scrollbar moves the Listbox.  Scanning a Listbox (dragging an item  with
       the left mouse button) moves the scrollbar.

            #!/usr/bin/perl -w
            use Tk;
            use strict;

            my $mw = MainWindow->new;
            my $box = $mw->Listbox(
                -relief => 'sunken',
                -height  => 5,
                -setgrid => 1,
           );
           my @items = qw(One Two Three Four Five Six Seven
                          Eight Nine Ten Eleven Twelve);
           foreach (@items) {
              $box->insert('end', $_);
           }
           my $scroll = $mw->Scrollbar(-command => ['yview', $box]);
           $box->configure(-yscrollcommand => ['set', $scroll]);
           $box->pack(-side => 'left', -fill => 'both', -expand => 1);
           $scroll->pack(-side => 'right', -fill => 'y');

           MainLoop;

       Note that there's a convenience method Scrolled which helps constructing
       widgets with automatically managed scrollbars.

Canvases and tags
       One  of  the  most  powerful  widgets  in Tk is the Canvas window.  In a
       Canvas window, you can draw simple graphics and include  other  widgets.
       The  Canvas  area may be larger than the visible window, and may then be
       scrolled.  Any item you draw on the canvas  has  its  own  id,  and  may
       optionally  have one or more tags.  You may refer to any item by its id,
       and may refer to any group of items by  a  common  tag;  you  can  move,
       delete,  or  change  groups  of items using these tags, and you can bind
       actions to tags.  For a properly designed (often structured) Canvas, you
       can specify powerful actions quite simply.

       In the example below, actions are bound to circles  (single  click)  and
       blue items (double-click); obviously, this can be extended to any tag or
       group of tags.

           #!/usr/bin/perl -w
           use Tk;
           use strict;

           # Create B<MainWindow> and canvas
           my $mw = MainWindow->new;
           my $canvas = $mw->Canvas;
           $canvas->pack(-expand => 1, -fill => 'both');

           # Create various items
           create_item($canvas, 1, 1, 'circle', 'blue', 'Jane');
           create_item($canvas, 4, 4, 'circle', 'red', 'Peter');
           create_item($canvas, 4, 1, 'square', 'blue', 'James');
           create_item($canvas, 1, 4, 'square', 'red', 'Patricia');

           # Single-clicking with left on a 'circle' item invokes a procedure
           $canvas->bind('circle', '<1>' => sub {handle_circle($canvas)});
           # Double-clicking with left on a 'blue' item invokes a procedure
           $canvas->bind('blue', '<Double-1>' => sub {handle_blue($canvas)});
           MainLoop;

           # Create an item; use parameters as tags (this is not a default!)
           sub create_item {
               my ($can, $x, $y, $form, $color, $name) = @_;

               my $x2 = $x + 1;
               my $y2 = $y + 1;
               my $kind;
               $kind = 'oval' if ($form eq 'circle');
               $kind = 'rectangle' if ($form eq 'square');
               $can->create(
                   ($kind, "$x" . 'c', "$y" . 'c',
                   "$x2" . 'c', "$y2" . 'c'),
                   -tags => [$form, $color, $name],
                   -fill => $color);
           }

           # This gets the real name (not current, blue/red, square/circle)
           # Note: you'll want to return a list in realistic situations...
           sub get_name {
               my ($can) = @_;
               my $item = $can->find('withtag', 'current');
               my @taglist = $can->gettags($item);
               my $name;
               foreach (@taglist) {
                   next if ($_ eq 'current');
                   next if ($_ eq 'red' or $_ eq 'blue');
                   next if ($_ eq 'square' or $_ eq 'circle');
                   $name = $_;
                   last;
               }
               return $name;
           }

           sub handle_circle {
               my ($can) = @_;
               my $name = get_name($can);
               print "Action on circle $name...\n";
           }

           sub handle_blue {
               my ($can) = @_;
               my $name = get_name($can);
               print "Action on blue item $name...\n";
           }

Perl/Tk and Unicode
       Perl/Tk  follows  Perl's model of handling Unicode. That is, if a string
       is correctly flagged as a "character" string in the sense like described
       in "TERMINOLOGY" in Encode, then Perl/Tk will very probably display  and
       handle this string correctly.

       Note  that  every variable which is passed somehow into a Perl/Tk method
       will be implicitely changed into an  internally  utf8-flagged  variable.
       Semantically  nothing  changes,  as  the  series of codepoints stays the
       same, but things will change when  variables  with  high-bit  iso-8859-1
       characters will be passed to the "outer" world. In this case you have to
       explicitly  mark  the  encoding  of  your  output stream if using IO, or
       encode the variables using Encode for other style of communication.

       This is the theory, now some examples.

       If you use non-iso-8859-1 characters in the source code, then use either
       the "use utf8;" or "use encoding 'encodingname'" pragma:

            use utf8;
            use Tk;
            my $x = "some characters using utf8 encoding";
            tkinit->Label(-text => $x)->pack;
            MainLoop;

       For data that comes from a file you have to specify the encoding  unless
       it's encoded as ascii or iso-8559-1:

            use Tk;
            open my $FH, "<:encoding(utf-8)", "filename" or die $!;
            # or for utf-16 data: open my $FH, "<:encoding(utf-16)", "filename" or die $!;
            my $data = <$FH>;
            tkinit->Label(-text => $data)->pack;
            MainLoop;

       Likewise, the encoding must be specified for all data which is read from
       Tk  widgets  and  that  shall be output into a file. For the output, the
       encoding should be always specified, even if it is iso-8859-1:

            use Tk;
            $mw = tkinit;
            $mw->Entry(-textvariable => \$input)->pack;
            $mw->Button(
                -text => "Write to file",
                -command => sub {
                    open my $FH, ">:encoding(iso-8859-1)", "filename" or die $!;
                    print $FH $input;
                },
            )->pack;
            MainLoop;

       Note that Tk is Unicode-capable. So you need to  be  prepared  that  the
       user  has  the  appropriate  input  methods activated to enter non-ascii
       characters. If an output encoding is used which does not cover the whole
       of Unicode codepoints then a warning will be  issued  when  writing  the
       file, like this:

           "\x{20ac}" does not map to iso-8859-1 at /usr/local/lib/perl5/site_perl/5.8.8/mach/Tk.pm line 250.

       Also, the same hexadecimal notation will be used as replacements for the
       unhandled characters.

       Handling  encoding  in  I/O is pretty simple using the "encoding" PerlIO
       layer, as described above. In other cases, such  as  when  dealing  with
       databases, encoding the data usually has to be done manually, unless the
       database  driver  has  some means for automatically do this for you.  So
       when working with a MySQL database, one could use:

            use Tk;
            use DBI;
            use Encode qw(encode);
            $mw = tkinit;
            $mw->Entry(-textvariable => \$input)->pack;
            $mw->Button(
                -text => "Write to database",
                -command => sub {
                    my $dbh = DBI->connect("dbi:mysql:test", "root", "") or die;
                    my $encoded_input = encode("iso-8859-1", $input);
                    $dbh->do("INSERT INTO testtable VALUES (?)", undef, $encoded_input) or die;
                },
            )->pack;
            MainLoop;

       Unfortunately, there are still places in Perl ignorant of  Unicode.  One
       of  these  places  are  filenames.  Consequently,  the file selectors in
       Perl/Tk do not handle encoding of  filenames  properly.  Currently  they
       suppose  that  filenames  are  in  iso-8859-1 encoding, at least on Unix
       systems. As soon as Perl has  a  concept  of  filename  encodings,  then
       Perl/Tk will also implement such schemes.

perl v5.40.1                       2025-04-13                    UserGuide(3pm)

Generated by dwww version 1.16 on Sat Oct 3 07:34:48 CEST 2026.