Before we end this chapter, and you become engrossed in the details of Perl/Tk, we'd like to give you some suggestions on programming style and window design. Bear with us, this won't take long and might save you a lot of time in the future.
The code in a Perl/Tk script can get quite cumbersome and clunky because of all the option/value pairs used to define and configure each widget. There are several ways to format the code to deal with readability (and in some cases, "edit-ability"). Most just involve adding extra spaces or tabs to line up different portions of code. Once you get used to seeing the code, it won't seem quite so mysterious and unwieldy.
One coding style places each option/value pair on a separate line:
$bttn = $parent->Button(-text => "my text", -command => sub { exit }, -width => 10, -height => 10);
With this style, it is extremely obvious what the pairs are and what value is associated with which option. (You could also go to the extreme of aligning each => to make nice columns, depending on how much time you have to press the spacebar.) Some people like to start the option/value pairs on the next line and put the ending ); on its own separate line, after the last option/value pair, which retains the comma for formatting ease:
$bttn = $parent->Button( -text => "Exit", -command => sub { exit }, -width => 10, -height => 10, );
This makes the code easier to edit; an option/value pair can be added or deleted on each line without having to mess with parentheses, semicolons, or commas. It also keeps the next lines closer to the left side of the page, so if you have several indentation levels, you don't end up with code quite so deeply nested to the right.
In either case, Emacs users may find the functionality of cperl-mode.el handy. This is an Emacs initialization file that adds color highlighting and special formatting that makes editing Perl code more efficient. You can find the file in the standard Perl distribution, in the perl-5.6.0/emacs directory.
Sometimes if there are only one or two option/value pairs, it makes sense to leave them all on the same line and conserve a little bit of space:
$bttn = $parent->Button(-text => "my text", -command => sub { exit });
You'll eventually come up with a style that works for the way you read and edit code. Whichever way you choose, try to be consistent throughout your scripts in case someone else takes over the maintenance of your code (it might even be you, a year or more down the road).
Sometimes your programs run away from you, getting so large and unwieldy that it becomes hard to remember what a particular variable was pointing to. If there are over 10 Buttons in a program, we would be hard-pressed to figure out which Button was $button3 without digging through a bunch of code.
So we've established a naming convention for our code. You don't need to use our convention, but it'll hopefully inspire you to come up with your own. Otherwise, we hope you have a really good memory.
For Buttons, you might use _b, _bttn, or Button as a type of qualifier to the variable name. For instance, you could name the Button in the Hello World example $done_b, $done_bttn,or$doneButton.
The topmost widget in an application's widget hierarchy is the MainWindow. Throughout this book, we use the variable $mw to represent this widget. You will see other programs use $main, $top, or $mainwindow as well.
Table 1-1 lists widget types and suggested naming conventions for them. Replace "blah" with a sensible description of the widget's purpose (e.g., exit). If you use this convention, you'll always know what type of widget you're working with.
Widget type |
Suggested name |
Examples |
---|---|---|
Button |
$blah_b, $blah_bttn, or $blahButton |
$exit_b, $apply_b, $newButton |
Canvas |
$blah_canvas or $blahCanvas |
$main_canvas, $tinyCanvas |
Checkbutton |
$blah_cb or $blahCheckbutton |
|
Entry |
$blah_e or $blahEntry |
$name_e, $addressEntry |
Frame |
$blah_f or $blahFrame |
$main_f, $left_f, $canvasFrame |
Label |
$blah_l or $blahLabel |
$name_l, $addressLabel |
Listbox |
$blah_lb or $blahListbox |
$teams_lb, $teamsListbox |
Menu |
$blah_m or $blahMenu |
$file_m, $edit_m, $helpMenu |
Radiobutton |
$blah_rb or $blahRadiobutton |
$blue_rb, $grey_rb, $redRadiobutton |
Scale |
$blah_scale or $blahScale |
$age_scale, $incomeScale |
Scrollbar |
$blah_scroll, $blah_sbar, or $blahScroll |
$x_scroll, $yScroll |
Text |
$blah_t or $blahText |
$file_text, $commentText |
Toplevel |
$blah_w or $blahWindow |
$main_w, $fileopenWindow |
Before you decide what events to handle, it is worthwhile to spend some time sketching out a few windows on paper and deciding what should happen (from the user's perspective) when you click a button or invoke a menu item.
A GUI often makes the application look much more polished and purposeful than a command-line interface does, but it's easy to go overboard with a GUI and end up with something ugly, clunky, and impossible to navigate. So here are some things to consider when deciding how the GUI should look:
Every widget should have a purpose that is intuitive and informative.
Think about the way a user will use an application and design accordingly.
Don't try to cram everything your application does into one window.
Don't always try to separate everything into different windows. Sometimes the application is so simple that one window is all you need.
Colors are great, but there are a lot of color-blind people out there. The same applies to fonts: many folks cannot read very small fonts. If you insist on using color and particular fonts, allow them to be customized via the resource database, through a file, or through the application itself.
Some widgets do their jobs better than others. Use the proper widget for the job.
Copyright © 2002 O'Reilly & Associates. All rights reserved.