Path: usenet.cis.ufl.edu!usenet.eel.ufl.edu!gatech!lepidopteran.cse.psu.edu!uwm.edu!math.ohio-state.edu!magnus.acs.ohio-state.edu!csn!news-1.csn.net!ub!newsstand.cit.cornell.edu!lnsnews.lns.cornell.edu!lns62.lns.cornell.edu!PVHP From: pvhp@lns62.lns.cornell.edu (Peter Prymmer) Newsgroups: comp.lang.perl.tk,comp.lang.perl.announce,comp.answers,news.answers Subject: comp.lang.perl.tk FAQ part2 of 5 Followup-To: comp.lang.perl.tk Date: Mon, 15 Apr 1996 09:01:57 GMT Organization: Wilson Lab, Cornell U., Ithaca, NY, 14853 Lines: 842 Approved: pvhp@lns62.lns.cornell.edu (Peter Prymmer) Expires: Mon, 20 May 1996 09:01:47 GMT Message-ID: <009A0E11.228A1BB0@lns62.lns.cornell.edu> Reply-To: PVHP@lns62.lns.cornell.edu NNTP-Posting-Host: lns62.lns.cornell.edu Xref: usenet.cis.ufl.edu comp.lang.perl.tk:1703 comp.lang.perl.announce:321 comp.answers:17996 news.answers:69925 Summary: comp.lang.perl.tk Frequently Asked Questions. Archive-name: perl-faq/ptk-faq/part2 Posting-Frequency: monthly Last-modified: Mon Apr 15 03:41:28 EDT 1996 URL: http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.html Version: 0.02 Supersedes: <0099F5AC.CAE60760@lns62.lns.cornell.edu> URL (Hypertext-split): http://w4.lns.cornell.edu/~pvhp/ptk/ptkTOC.html URL (Plaintext): http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.txt Image-supplement: http://w4.lns.cornell.edu/~pvhp/ptk/ptkIMG.html ftp-Archive: ftp://ftp.ccd.bnl.gov/pub/ptk/ptkFAQ.txt ftp-Archive: ftp://ftp.wpi.edu/perl5/pTk-FAQ ftp-Archive: ftp://rtfm.mit.edu/pub/usenet/perl-faq/ptk-faq/ e-mail-Archive: ptkfaq@pubweb.bnl.gov gopher-Archive: 128.84.219.153 Perl/Tk FAQ part 2 of 5 - Programming ************************************* ______________________________________________________________________ 9. 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... As of Tk-b9(.01) the - sign in front of options (like -text in the above example) will be optional (hence ->Button(text => 'Press me!')). ______________________________________________________________________ 9.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 :-) ______________________________________________________________________ 9.2. 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 Tk-b#/ 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. ______________________________________________________________________ 9.3. 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 [15.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(); ______________________________________________________________________ 9.4. 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('' => 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 , for semi-global bindings you need to bind to all the relevant widgets in your application), '' can be things like: or or