home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _6db0ad610d2ca0dce10d307985b2437f < prev    next >
Encoding:
Text File  |  2004-06-01  |  15.4 KB  |  484 lines

  1. =head1 NAME
  2.  
  3. Perl/Tk - Writing Tk applications in Perl 5
  4.  
  5. =for category Introduction
  6.  
  7. =head1 DESCRIPTION
  8.  
  9. This document is for beginners.  It assumes you know some B<Perl>, and
  10. have it and Tk running.  If you are I<not> currently reading this
  11. document courtesy of the B<widget> demonstration program, please be
  12. sure to run B<widget>, as it will show you the various widget types
  13. supported by Tk and how to use them. B<widget> should be installed in
  14. your default path, so type I<widget> at a command prompt.
  15.  
  16. Here are links to other novice tutorials:
  17.  
  18. http://www.lehigh.edu/~sol0/ptk/tpj1.html
  19. http://www.lehigh.edu/~sol0/ptk/perlmonth01/pm1.html
  20.  
  21. I<Mastering Perl/Tk> is the definitive book on Perl/Tk:
  22.  
  23. http://www.oreilly.com/catalog/mastperltk
  24.  
  25. =head1 Some Background
  26.  
  27. Tk GUI programming is event-driven.  (This may already be familiar to
  28. you.)  In event-driven programs, the main GUI loop is outside of the
  29. user program and inside the GUI library.  This loop - initiated by
  30. calling B<MainLoop> - watches all events of interest and activates
  31. the correct handler procedures to handle these events.  Some of these
  32. handler procedures may be user-supplied; others will be part of the
  33. library.
  34.  
  35. For a programmer, this means that you're not watching what is happening;
  36. instead, you are requested by the toolkit to perform actions whenever
  37. necessary.
  38. So, you're not watching for 'raise window / close window / redraw window'
  39. requests, but you tell the toolkit which routine will handle such cases,
  40. and the toolkit will call the procedures when required. These procedures
  41. are known as I<callbacks>, and some of them you write yourself.
  42.  
  43. =head1 First Requirements
  44.  
  45. B<Perl> programs that use Tk need to include C<use Tk>.
  46. A program should also use C<use strict> and the B<-w> switch to ensure
  47. the program is working without common errors.
  48.  
  49. Any Perl/Tk application starts by creating the Tk B<MainWindow>.  You
  50. then create items inside the B<MainWindow>, and/or create new windows
  51. called B<Toplevel>s that also contain child items, before starting the
  52. B<MainLoop>, which is the last logical statment in your program. You
  53. can also create more items and windows while you're running, using
  54. callbacks.  Items are only shown on the display after they have been
  55. arranged by a I<geometry manager> like B<pack>; more information on
  56. this later.  B<MainLoop> starts the GUI and handle all events.  That's
  57. all there is to it!.  A trivial one-window example is shown below:
  58.  
  59.     #!/usr/bin/perl -w    
  60.     use Tk;
  61.     use strict;
  62.  
  63.     my $mw = MainWindow->new;
  64.     $mw->Label(-text => 'Hello, world!')->pack;
  65.     $mw->Button(
  66.         -text    => 'Quit',
  67.         -command => sub { exit },
  68.     )->pack;
  69.     MainLoop;
  70.  
  71. Please run this example.  It shows you two widget types, a B<Label>
  72. and a B<Button>, and how they are packed. When clicked, the <Button>
  73. widget invokes the callback specified by the -command option.  Finally,
  74. note the typical Tk style using C<-option> =E<gt> C<value> pairs.
  75.  
  76. =head1 Widget creation
  77.  
  78. Tk windows and widgets are hierarchical, S<i.e. one> window includes
  79. one or more other windows.  You create the first Tk window using
  80. C<MainWindow-E<gt>new>.  This returns a window handle, assigned to
  81. C<$mw> in the example above.  Keep track of the main handle, commonly
  82. called a I<widget reference>.
  83.  
  84. You can use any Tk handle to create child widgets within the window (or
  85. widget).  This is done by calling the Tk constructor method on the
  86. variable.  In the example above, the C<Label> method called from
  87. C<$mw> creates a B<Label> widget inside the B<MainWindow>.  In the
  88. constructor call, you can specify various options; you can later add
  89. or change options for any widget using the B<configure> method, which
  90. takes the same parameters as the constructor.  The one exception to
  91. the hierarchical structure is the B<Toplevel> constructor, which
  92. creates a new outermost window.
  93.  
  94. After you create any widget (other than the B<MainWindow> or
  95. B<Toplevel>s, you must render it by calling B<pack>.  (This is not
  96. entirely true; more later).  If you do not need to refer to the widget
  97. after construction and packing, call B<pack> off the constructor
  98. results, as shown for the B<Label> and B<utton> in the example above.  Note
  99. that the result of the compound call is the result of B<pack>, which
  100. is a valid Tk handle.
  101.  
  102. Windows and widgets are deleted by calling B<destroy> on them;
  103. this will delete and un-draw the widget and all its children.
  104.  
  105. =head1 Standard Tk widgets
  106.  
  107. Here is an itemize of the standard Tk widget set.
  108.  
  109. =over 4
  110.  
  111. =item Button
  112.  
  113. =item Canvas
  114.  
  115. =item Checkbutton
  116.  
  117. =item Entry
  118.  
  119. =item Frame
  120.  
  121. =item Label
  122.  
  123. =item Labelframe
  124.  
  125. =item Listbox
  126.  
  127. =item Menu
  128.  
  129. =item Menubutton
  130.  
  131. =item Message
  132.  
  133. =item Panedwindow
  134.  
  135. =item Radiobutton
  136.  
  137. =item Scale
  138.  
  139. =item Scrollbar
  140.  
  141. =item Spinbox
  142.  
  143. =item Text
  144.  
  145. =item Toplevel
  146.  
  147. =back
  148.  
  149. Perl/Tk provides an equal number of new widgets, above and beyond this
  150. core set.
  151.  
  152. =over 4
  153.  
  154. =item Adjuster
  155.  
  156. =item Ballon
  157.  
  158. =item BrowseEntry
  159.  
  160. =item ColorEditor
  161.  
  162. =item DirTree
  163.  
  164. =item ErrorDialog
  165.  
  166. =item FileSelect
  167.  
  168. =item HList
  169.  
  170. =item LabEntry
  171.  
  172. =item LabFrame
  173.  
  174. =item NoteBook
  175.  
  176. =item Optionmenu
  177.  
  178. =item Pane
  179.  
  180. =item ProgressBar
  181.  
  182. =item ROText
  183.  
  184. =item Table
  185.  
  186. =item TextUndo
  187.  
  188. =item Tiler
  189.  
  190. =item TList
  191.  
  192. =item Tree
  193.  
  194. =back
  195.  
  196. =head1 Variables and callback routines
  197.  
  198. Most graphical interfaces are used to set up a set of values and conditions,
  199. and then perform the appropriate action.  The Tk toolkit is different
  200. from your average text-based prompting or menu driven system in that you do
  201. not collect settings yourself, and decide on an action based on an
  202. input code; instead, you leave these
  203. values to your toolkit and only get them when the action is performed.
  204.  
  205. So, where a traditional text-based system would look like this:
  206.  
  207.     #!/usr/bin/perl -w
  208.     use strict;
  209.  
  210.     print "Please type a font name\n";
  211.     my $font = <>; chomp $font;
  212.     # Validate font
  213.  
  214.     print "Please type a file name\n";
  215.     my $filename = <>; chomp $filename;
  216.     # Validate filename
  217.  
  218.     print "Type <1> to fax, <2> to print\n";
  219.     my $option = <>; chomp $option;
  220.     if ($option eq 1) {
  221.         print "Faxing $filename in font $font\n";
  222.     } elsif ($option eq 2) {
  223.         print "Now sending $filename to printer in font $font\n";
  224.     }
  225.  
  226. The slightly larger example below shows how to do this in Tk.
  227. Note the use of callbacks.  Note, also, that Tk handles the values, and
  228. the subroutine uses the method B<get> to get at the values.
  229. If a user changes his mind and wants to change the font again,
  230. the application never notices; it's all handled by Tk.
  231.  
  232.     #!/usr/bin/perl -w
  233.     use Tk;
  234.     use strict;
  235.  
  236.     my $mw = MainWindow->new;
  237.  
  238.     $mw->Label(-text => 'File Name')->pack;
  239.     my $filename = $mw->Entry(-width => 20);
  240.     $filename->pack;
  241.  
  242.     $mw->Label(-text => 'Font Name')->pack;
  243.     my $font = $mw->Entry(-width => 10);
  244.     $font->pack;
  245.  
  246.     $mw->Button(
  247.         -text => 'Fax',
  248.         -command => sub{do_fax($filename, $font)}
  249.     )->pack;
  250.  
  251.     $mw->Button(
  252.         -text => 'Print',
  253.         -command => sub{do_print($filename, $font)}
  254.     )->pack;
  255.  
  256.     MainLoop;
  257.  
  258.     sub do_fax {
  259.         my ($file, $font) = @_;
  260.         my $file_val = $file->get;
  261.         my $font_val = $font->get;
  262.         print "Now faxing $file_val in font $font_val\n";
  263.     }
  264.  
  265.     sub do_print {
  266.         my ($file, $font) = @_;
  267.         my $file_val = $file->get;
  268.         my $font_val = $font->get;
  269.         print "Sending file $file_val to printer in font $font_val\n";
  270.     }
  271.  
  272. =head1 The packer - grouping with Frame widgets
  273.  
  274. In the examples above, you must have noticed the B<pack> calls.  This
  275. is one of the more complicated parts of Tk.  The basic idea is that
  276. any window or widget should be subject to a Tk geometry manager; the
  277. I<packer> is one of the placement managers, and Bgrid> is another.
  278.  
  279. The actions of the packer are rather simple: when applied
  280. to a widget, the packer positions that widget on the indicated position
  281. within the remaining space in its parent.  By default, the position is
  282. on top; this means the next items will be put below.  You can also
  283. specify the left, right, or bottom positions.  Specify position
  284. using B<-side =E<gt> 'right'>.
  285.  
  286. Additional packing parameters specify the behavior of the widget when
  287. there is some space left in the B<Frame> or when the window size is
  288. increased.  If widgets should maintain a fixed size, specify nothing;
  289. this is the default.  For widgets that you want to fill up the current
  290. horizontal and/or vertical space, specify B<-fill =E<gt> 'x'>, B<y>,
  291. or B<both>; for widgets that should grow, specify B<-expand =E<gt> 1>.
  292. These parameters are not shown in the example below; see the B<widget>
  293. demonstration.
  294.  
  295. If you want to group some items within a window that have a different
  296. packing order than others, you can include them in a Frame.  This is a
  297. do-nothing window type that is meant for packing or filling (and to
  298. play games with borders and colors).
  299.  
  300. The example below shows the use of pack and Frames:
  301.  
  302.     #!/usr/bin/perl -w
  303.     use Tk;
  304.     use strict;
  305.  
  306.     # Take top and the bottom - now implicit top is in the middle
  307.     my $mw = MainWindow->new;
  308.     $mw->title( 'The MainWindow' );
  309.     $mw->Label(-text => 'At the top (default)')->pack;
  310.     $mw->Label(-text => 'At the bottom')->pack(-side => 'bottom');
  311.     $mw->Label(-text => 'The middle remains')->pack;
  312.  
  313.     # Since left and right are taken, bottom will not work...
  314.     my $top1 = $mw->Toplevel;
  315.     $top1->title( 'Toplevel 1' );
  316.     $top1->Label(-text => 'Left')->pack(-side => 'left');
  317.     $top1->Label(-text => 'Right')->pack(-side => 'right');
  318.     $top1->Label(-text => '?Bottom?')->pack(-side => 'bottom');
  319.  
  320.     # But when you use Frames, things work quite alright
  321.     my $top2 = $mw->Toplevel;
  322.     $top2->title( 'Toplevel 2' );
  323.     my $frame = $top2->Frame;
  324.     $frame->pack;
  325.     $frame->Label(-text => 'Left2')->pack(-side => 'left');
  326.     $frame->Label(-text => 'Right2')->pack(-side => 'right');
  327.     $top2->Label(-text => 'Bottom2')->pack(-side => 'bottom');
  328.  
  329.     MainLoop;
  330.  
  331. =head1 More than one window
  332.  
  333. Most real applications require more than one window.  As you just saw,
  334. you can create more outermost windows by using a B<Toplevel> widget.
  335. Each window is independent; destroying a B<Toplevel> window does not
  336. affect the others as long as they are not a child of the closed
  337. B<Toplevel>.  However, exiting the B<MainWindow> will destroy all remaining
  338. B<Toplevel> widgets and end the application.  The
  339. example below shows a trivial three-window application:
  340.  
  341.     #!/usr/bin/perl -w
  342.     use Tk;
  343.     use strict;
  344.  
  345.     my $mw = MainWindow->new;
  346.     fill_window($mw, 'Main');
  347.     my $top1 = $mw->Toplevel;
  348.     fill_window($top1, 'First top-level');
  349.     my $top2 = $mw->Toplevel;
  350.     fill_window($top2, 'Second top-level');
  351.     MainLoop;
  352.  
  353.     sub fill_window {
  354.         my ($window, $header) = @_;
  355.         $window->Label(-text => $header)->pack;
  356.         $window->Button(
  357.             -text    => 'close',
  358.             -command => [$window => 'destroy']
  359.         )->pack(-side => 'left');
  360.         $window->Button(
  361.             -text    => 'exit',
  362.             -command => [$mw => 'destroy']
  363.         )->pack(-side => 'right');
  364.     }
  365.  
  366. =head1 More callbacks
  367.  
  368. So far, all callback routines shown called a user procedure.
  369. You can also have a callback routine call another Tk routine.
  370. This is the way that scroll bars are implemented: scroll-bars
  371. can call a Tk item or a user procedure, whenever their position
  372. has changed.  The Tk item that has a scrollbar attached calls the
  373. scrollbar when its size or offset has changed.  In this way,
  374. the items are linked.  You can still ask a scrollbar's position,
  375. or set it by hand - but the defaults will be taken care of.
  376.  
  377. The example below shows a B<listbox> with a scroll bar.  Moving
  378. the scrollbar moves the B<listbox>.  Scanning a B<listbox> (dragging
  379. an item with the left mouse button) moves the scrollbar.
  380.  
  381.      #!/usr/bin/perl -w
  382.      use Tk;
  383.      use strict;
  384.  
  385.      my $mw = MainWindow->new;
  386.      my $box = $mw->Listbox(
  387.          -relief => 'sunken',
  388.          -height  => 5,
  389.          -setgrid => 1,
  390.     );
  391.     my @items = qw(One Two Three Four Five Six Seven
  392.                    Eight Nine Ten Eleven Twelve);
  393.     foreach (@items) {
  394.        $box->insert('end', $_);
  395.     }
  396.     my $scroll = $mw->Scrollbar(-command => ['yview', $box]);
  397.     $box->configure(-yscrollcommand => ['set', $scroll]);
  398.     $box->pack(-side => 'left', -fill => 'both', -expand => 1);
  399.     $scroll->pack(-side => 'right', -fill => 'y');
  400.  
  401.     MainLoop;
  402.  
  403. =head1 Canvases and tags
  404.  
  405. One of the most powerful widgets in Tk is the B<Canvas> window.
  406. In a <Canvas> window, you can draw simple graphics and include
  407. other widgets.  The <Canvas> area may be larger than the visible window,
  408. and may then be scrolled.  Any item you draw on the canvas has its own id,
  409. and may optionally have one or more I<tags>.  You may refer to any
  410. item by its id, and may refer to any group of items by a common tag;
  411. you can move, delete, or change groups of items using these tags,
  412. and you can I<bind> actions to tags.  For a properly designed (often
  413. structured) B<Canvas>, you can specify powerful actions quite simply.
  414.  
  415. In the example below, actions are bound to circles (single click)
  416. and blue items (double-click); obviously, this can be extended to any
  417. tag or group of tags.
  418.  
  419.     #!/usr/bin/perl -w
  420.     use Tk;
  421.     use strict;
  422.  
  423.     # Create B<MainWindow> and canvas
  424.     my $mw = MainWindow->new;
  425.     my $canvas = $mw->Canvas;
  426.     $canvas->pack(-expand => 1, -fill => 'both');
  427.  
  428.     # Create various items
  429.     create_item($canvas, 1, 1, 'circle', 'blue', 'Jane');
  430.     create_item($canvas, 4, 4, 'circle', 'red', 'Peter');
  431.     create_item($canvas, 4, 1, 'square', 'blue', 'James');
  432.     create_item($canvas, 1, 4, 'square', 'red', 'Patricia');
  433.  
  434.     # Single-clicking with left on a 'circle' item invokes a procedure
  435.     $canvas->bind('circle', '<1>' => sub {handle_circle($canvas)});
  436.     # Double-clicking with left on a 'blue' item invokes a procedure
  437.     $canvas->bind('blue', '<Double-1>' => sub {handle_blue($canvas)});
  438.     MainLoop;
  439.  
  440.     # Create an item; use parameters as tags (this is not a default!)
  441.     sub create_item {
  442.         my ($can, $x, $y, $form, $color, $name) = @_;
  443.  
  444.         my $x2 = $x + 1;
  445.         my $y2 = $y + 1;
  446.         my $kind;
  447.         $kind = 'oval' if ($form eq 'circle');
  448.         $kind = 'rectangle' if ($form eq 'square');
  449.         $can->create(
  450.             ($kind, "$x" . 'c', "$y" . 'c',
  451.             "$x2" . 'c', "$y2" . 'c'),
  452.             -tags => [$form, $color, $name],
  453.             -fill => $color);
  454.     }
  455.  
  456.     # This gets the real name (not current, blue/red, square/circle)
  457.     # Note: you'll want to return a list in realistic situations...
  458.     sub get_name {
  459.         my ($can) = @_;
  460.         my $item = $can->find('withtag', 'current');
  461.         my @taglist = $can->gettags($item);
  462.         my $name;
  463.         foreach (@taglist) {
  464.             next if ($_ eq 'current');
  465.             next if ($_ eq 'red' or $_ eq 'blue');
  466.             next if ($_ eq 'square' or $_ eq 'circle');
  467.             $name = $_;
  468.             last;
  469.         }
  470.         return $name;
  471.     }
  472.  
  473.     sub handle_circle {
  474.         my ($can) = @_;
  475.         my $name = get_name($can);
  476.         print "Action on circle $name...\n";
  477.     }
  478.  
  479.     sub handle_blue {
  480.         my ($can) = @_;
  481.         my $name = get_name($can);
  482.         print "Action on blue item $name...\n";
  483.     }
  484.