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