Learn the Perl/Tk module, Part 1: The basics of Perl/Tk

Although Perl-based Web interfaces have limitations, Perl is one of the most commonly used Web development languages. UNIX® users who have a programming background in shell scripting, Perl, or another language can breathe new life into Perl-based Web interfaces by using the Perl/Tk module.

Share:

Adam Cormany, UNIX Systems Engineer, Scientific Games Corporation

Adam Cormany is currently the manager of the National Data Center, but he has also been a UNIX systems engineer, a UNIX administrator, and operations manager for Scientific Games Corporation. Adam has worked extensively with AIX as well as in Solaris and Red Hat Linux administration for more than 10 years. He is an IBM eServer-Certified Specialist in pSeries AIX System Administration. In addition to administration, Adam has extensive knowledge of shell scripting in Bash, CSH, and KSH as well as programming in C, PHP, and Perl. You can reach him at acormany@yahoo.com.



16 October 2007

Also available in Chinese Russian

The Perl language is usually used by IBM® AIX® operating system administrators and developers, and it can be found on nearly every successful Web site and most AIX systems. Although Perl scripts are powerful, they produce a Web interface that lacks a graphical front end, and the user has to type information instead of using the mouse, which can be an unsatisfying experience for the customer. This problem has been resolved with the introduction to the Tk module in Perl. An administrator or developer can quickly breathe new life into their Perl script with the Tk module and satisfy their customer's desire for an X11 product.

What is Perl?

Perl, or Practical Extraction and Reporting Languages, was created by Larry Wall in 1987 as a means to simplify his programming work. Since its conception, Perl has evolved into a globally used language and is a staple for most administrators and developers.

What is the Perl/Tk module?

The Perl/Tk module, also known as pTk or ptk, is a Perl module designed to create widgets and other commonly used graphical objects to form a graphical user interface (GUI). Using the module to create a GUI enhances the look and feel of a program and helps the end user navigate through the program and its functions. One major advantage of using the Perl/Tk module is that the resulting application can be cross-platform, meaning the same GUI application can be used on UNIX®, Linux®, Macintosh, Microsoft® Windows®, or any other operating system that has Perl and the Perl/Tk module installed.

Where to get the Perl/Tk module

Before you write an application with the Perl/Tk module, you must verify that Perl and the Perl/Tk module are installed. Although Perl is commonly installed on computers, the Perl/Tk module isn't. One way to verify if Perl is installed is to type perl --version at the command line. If Perl isn't installed, please refer to the installation guide found on Perl's Web site (see Resources).

Once you've located or installed Perl on your computer, the next step is to determine whether the Perl/Tk module needs to be installed. A simple way to verify if a module is installed is to type perl -e "use module" at the command prompt. To verify if the Perl/Tk module is installed, execute the following command:

perl -e "use Tk"

If the module is found, the command executes and returns to a command prompt. However, if the module isn't found, an error message similar to the following is displayed:

        Can't locate Tk.pm in @INC (@INC contains: /opt/ActivePerl-5.8/site/lib 
        /opt/ActivePerl-5.8/lib .) at -e line 1.
        BEGIN failed--compilation aborted at -e line 1.

Keep in mind that Perl is case sensitive: perl –e "use Tk" and perl –e "use tk" are two different statements trying to use two different modules (Tk and tk).

If the module isn't found, the next step is to download and install it. You can do so a couple of ways.

If you're using UNIX or Linux, one way to download and install Perl modules is to use the Comprehensive Perl Archive Network (CPAN). Type the following at the command prompt:

        perl –MCPAN –e shell
        install Bundle::CPAN
        reload cpan
        install Tk

If you're using Windows, a similar approach is to use Perl Package Manager (PPM). At a command prompt, type ppm to start the GUI and download the Tk module.

Once the installation is complete, reverify that Perl can find the module by executing perl –e "use Tk".

Create a window

Now that the computer has Perl and the Perl/Tk module installed, it's time to write your first GUI program through the module. You'll start with a simple Hello World program. With your preferred text editor, create a file named helloworld.pl, and enter the following text in the file:

        #!/usr/bin/perl -w
        # Display Hello World program
        
        use Tk;
        use strict;
        
        my $mw = MainWindow->new;
        $mw->geometry("200x100");
        $mw->title("Hello World!!!");
        
        $mw->Label(-text => 'Hello World')->pack();
        
        $mw->Button(-text => "Close", -command =>sub{exit})->pack();
        
        MainLoop;

Executing this script generates the GUI application, as shown in Figure 1 below.

Figure 1. Hello World example
Hello World example

Let's break this script down, line by line:

      #!/usr/bin/perl -w

The first part (/usr/bin/perl) defines the location where the Perl executable resides on the computer and instructs the computer to use this copy of the Perl executable to execute the helloworld.pl file. The second part of this line (-w) is a valuable tool in Perl: It enables warnings when executing the script, informing the end user of any possible errors found.

Comments and text that shouldn't be evaluated at execution are preceded with an octothorpe or # symbol:

# Display Hello World program

In order for a Perl script to use the Tk module, it must be included—in other words, use Tk. Adding the use strict statement to a Perl script also helps find any possible typos or logic errors:

use Tk;
use strict;

To create the primary window of the application, use MainWindow and assign it to $mw. $mw acts as the parent to all other widgets:

my $mw = MainWindow->new;

Set the main window size to 200 x 100 and title the window "Hello World!!!:"

$mw->geometry("200x100");
$mw->title("Hello World!!!");

Create a label inside the main window with the caption Hello World. At the end of the label creation is an additional function, pack, which is the geometry manager. It's used on widgets to calculate the space allocated on the widget's parent; it also displays the widget:

$mw->Label(-text => 'Hello World')->pack();

This line creates a Close button inside the main window. When activated by a mouse click or executed by the keyboard, this button exits the Perl script:

$mw->Button(-text => "Close", -command =>sub{exit})->pack();

Again, because this button takes up space on the main window, you need to use the pack function to calculate the space used.

Prior to executing MainLoop, everything in the script is read, defined, and prepared to execute. Then, when MainLoop is called, all functions and data read prior to that point are executed, and the GUI is displayed.

MainLoop;

Widgets

This section introduces widgets. It covers a few basic widgets and presents examples of each, including frames, text, entry, buttons, and labels.

What is a widget?

A widget is a graphical object that performs a specific function. Any graphical object in the Perl/Tk module can be considered a widget. When you think of a GUI application, the buttons, text, frames, and scrollbars are all widgets.

The following widget examples build a base for widgets discussed later in this article.

Frame

The frame widget is exactly what it's named: a frame or box. The frame is used to group other widgets.

Enter the following script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("200x100");
$mw->title("Frame Test");

$mw->Frame(-background => 'red')->pack(-ipadx => 50, -side => "left", -fill => "y");
$mw->Frame(-background => 'blue')->pack(-ipadx => 50, -side => "right", -fill => "y");

MainLoop;

When you execute this script, it generates the GUI application, as shown in Figure 2.

Figure 2. Frame widget example
Frame widget example

Let's break down the script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("200x100");
$mw->title("Frame Test");
…
…
MainLoop;

This portion was discussed in the previous example, so let's move on to the new statements.

Create a frame with the main window as the parent, and set the background color to red. Unlike previous examples of the pack method, a few options are included:

$mw->Frame(-background => 'red')->pack(-ipadx => 50, -side => "left", -fill => "y");

The first argument, ipadx, increases the frame's width by 100 (50 x 2). The second argument, side, adjusts the geometric position of the frame to the left side of its parent ($mw). The third argument allocates space in the frame in the direction of y (vertically).

This frame is similar to the previous frame, but the background is blue, and the position is on the right side of the main window:

$mw->Frame(-background => 'blue')->pack(-ipadx => 50, -side => "right", -fill => "y");

Text

The text widget creates an editable text workspace. Enter the following script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("200x100");
$mw->title("Text Test");

$mw->Text(-background => 'cyan', -foreground => 'white')->pack(-side => "top");

MainLoop;

Executing the script and typing in the window generates the GUI application, as shown in Figure 3.

Figure 3. Text widget example
Text widget example

In this example, the text widget is created with the main window as the parent:

$mw->Text(-background => 'cyan', -foreground => 'white')->pack(-side => "top");

Rather than changing only the background color, the foreground font color is changed as well. As always, the pack method is used to allocate space and display the widget.

Entry

The entry widget is similar to the text widget in that you can edit or enter text in the widget. The text widget lets you enter multiple lines of text, and the entry widget allows only a single line of text.

Enter the following script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("200x100");
$mw->title("Entry Test");

$mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "top");

MainLoop;

Executing the script and typing in the window generates the GUI application, as shown in Figure 4.

Figure 4. Entry widget example
Entry widget example

The only difference between the text widget and this one is the widget name:

$mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "top");

However, as the example shows, you can supply only one line of text.

Button

The button widget creates a button that can execute functions or commands when activated by the end user. Nearly all graphical programs include buttons, so it's handy to be familiar with the button widget.

The following example uses three buttons. The first, labeled Button 1, displays the message Button 1 pushed with an OK button. The second button, labeled Button 2, displays the message Button 2 pushed with both Yes and No buttons asking whether the user wants to exit the program. Depending on which button is clicked, a new message is displayed stating that either the Yes or No button was clicked and the program does or doesn't exit.

Here's the example script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("200x100");
$mw->title("Button Test");

my $button1 = $mw->Button(-text => "Button #1", -command => \&button1_sub)->pack();

my $button2 = $mw->Button(-text => "Button #2", -command => \&button2_sub)->pack();

sub button1_sub {
  $mw->messageBox(-message => "Button 1 Pushed", -type => "ok");
}

sub button2_sub {
  my $yesno_button = $mw->messageBox(-message => "Button 2 Pushed. Exit?",
                                        -type => "yesno", -icon => "question");

  $mw->messageBox(-message => "You pressed $yesno_button!", -type => "ok");

  if ($yesno_button eq "Yes") {
    $mw->messageBox(-message => "Ok, Exiting.", -type => "ok");
    exit;
  } else {
    $mw->messageBox(-message => "I didn't think so either.", -type => "ok");
  }
}

MainLoop;

Executing the script generates the GUI application, as shown in Figures 5 through 11.

Figure 5. Button widget example
Button widget example
Figure 6. Button 1 clicked
Button 1 clicked
Figure 7. Button 2 clicked
Button 2 clicked
Figure 8. No button clicked
No button clicked
Figure 9. Confirmation of No button clicked
Confirmation of No button clicked
Figure 10. Yes button clicked
Yes button clicked
Figure 11. Confirmation of Yes button clicked
Confirmation of Yes button clicked

This script is more complicated than the previous examples but, if you break it down, it's as easy to follow as the others. First, you create each button and assign the appropriate text to it (Button #1 or Button #2). Each button is linked to a command or function. The subroutines are appropriately called button1_sub and button2_sub:

my $button1 = $mw->Button(-text => "Button #1", -command => \&button1_sub)->pack();

my $button2 = $mw->Button(-text => "Button #2", -command => \&button2_sub)->pack();

When $button1 is clicked, the subroutine button1_sub is executed. Inside this function, a message box is created that displays the text Button 1 Pushed with a single button labeled OK. Because no further evaluations are performed on the OK button, the message box is destroyed and the main window regains focus.

sub button1_sub {
  $mw->messageBox(-message => "Button 1 Pushed", -type => "ok");
}

This subroutine is similar to the first except that it includes two buttons labeled Yes and No. Once the user clicks a button, a new message box appears that states which one they clicked. Then, another message box is displayed that states whether the program is exiting:

sub button2_sub {
  my $yesno_button = $mw->messageBox(-message => "Button 2 Pushed. Exit?",
                                         -type => "yesno", -icon => "question");

  $mw->messageBox(-message => "You pressed $yesno_button!", -type => "ok");

  if ($yesno_button eq "Yes") {
    $mw->messageBox(-message => "Ok, Exiting.", -type => "ok");
    exit;
  } else {
    $mw->messageBox(-message => "I didn't think so either.", -type => "ok");
  }
}

Label

A label is a non-editable text widget. Labels can be useful prior to text boxes and entry boxes. Enter the following example script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("200x100");
$mw->title("Entry Test");

$mw->Label(-text => "What's your name?")->pack(-side => "left");
$mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "right");

MainLoop;

Executing this script generates the GUI application, as shown in Figure 12.

Figure 12. Label widget example
Label widget example

The first line creates the label with the text What's your name?:

$mw->Label(-text => "What's your name?")->pack(-side => "left");
$mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "right");

To position the label to the left of the entry widget, you set pack to align to the left side. As in previous examples, an entry widget is created with a black background and white background. To position the entry to the right of the label widget, set pack to align to the right side.

Putting it all together

Now that you're familiar with a few widgets, let's put it all together in one script:

#!/usr/bin/perl -w

use Tk;
use strict;

my $mw = MainWindow->new;
$mw->geometry("500x200");
$mw->title("All-In-One Test");


my $main_frame = $mw->Frame()->pack(-side => 'top', -fill => 'x');

my $top_frame = $main_frame->Frame(-background => "red")->pack(-side => 'top',
                                                                   -fill => 'x');
my $left_frame = $main_frame->Frame(-background => "black")->pack(-side => 'left',
                                                                   -fill => 'y');
my $right_frame = $main_frame->Frame(-background => "white")->pack(-side => "right");

$top_frame->Label(-text => "All-In-One Test!", 
                                   -background => "red")->pack(-side => "top");
$left_frame->Label(-text => "Enter text to copy", -background => "black",
                      -foreground => "yellow")->pack(-side => "left");
my $copy_entry = $left_frame->Entry(-background => "white",
                                       -foreground => "red")->pack(-side => "left");
my $copy_button = $left_frame->Button(-text => "Copy Text",
                                -command => \&copy_entry)->pack(-side => "right");

my $clear_text = $right_frame->Button(-text => "Clear Text",
                                         -command => \&clear_entry)->pack(-side => "top");
my $paste_text = $right_frame->Text(-background => "white",
                                       -foreground => "black")->pack(-side => "top");

sub clear_entry {
  $paste_text->delete('0.0', 'end');
}

sub copy_entry {
  my $copied_text = $copy_entry->get();
  $paste_text->insert("end", $copied_text);
}

MainLoop;

Executing this script generates the GUI application, as shown in Figure 13.

Figure 13. All-in-one example
All-in-one example

Let's break it down like the other examples. First, you build a main frame and three frames inside it. These frames contain the other widgets and keep everything organized:

my $main_frame = $mw->Frame()->pack(-side => 'top', -fill => 'x');

my $top_frame = $main_frame->Frame(-background => "red")->pack(-side => 'top',
                                                                   -fill => 'x');
my $left_frame = $main_frame->Frame(-background => "black")->pack(-side => 'left',
                                                                   -fill => 'y');
my $right_frame = $main_frame->Frame(-background => "white")->pack(-side => "right");

Next, you add the labels: one in the top frame and another in the left frame:

$top_frame->Label(-text => "All-In-One Test!", 
                                   -background => "red")->pack(-side => "top");

$left_frame->Label(-text => "Enter text to copy", -background => "black", 
                                    -foreground => "yellow")->pack(-side => "left");

To accompany the label in the left frame, create an entry widget so that the user can type the text that they want copied. You also use a button widget to perform the copy function to copy the text to the right frame's text widget:

        my $copy_entry = $left_frame->Entry(-background => "white", 
                                     -foreground => "red")->pack(-side => "left");
        my $copy_button = $left_frame->Button(-text => "Copy Text", 
                                   -command => \&copy_entry)->pack(-side => "right");

Now let's look at the right frame. A button widget lets the user clear all text from the text widget:

        my $clear_text = $right_frame->Button(-text => "Clear Text", 
                                  -command => \&clear_entry)->pack(-side => "top");
        my $paste_text = $right_frame->Text(-background => "white", 
                                    -foreground => "black")->pack(-side => "top");

You also create a text widget so that the user can copy text from the entry widget and edit it if necessary.

These functions are the clear and copy subroutines:

sub clear_entry {
  $paste_text->delete('0.0', 'end');
}

sub copy_entry {
  my $copied_text = $copy_entry->get();
  $paste_text->insert("end", $copied_text);
}

The clear_entry function deletes all text starting from 0.0, or line 0 character 0, up to and including the end of the widget. The copy_entry function gets the text in the entry widget and inserts it into the text widget.

Conclusion

Introducing Perl with the Perl/Tk module into an AIX environment can benefit the developer, administrator, and customer or end user. You can enhance a script that might look dull to the customer into a professional-looking GUI application. It might take you a little while to get the hang of the widgets but, once you've mastered them, the results are worth the effort and time!

Resources

Learn

Get products and technologies

  • Perl: You can download the latest version here.
  • ActivePerl: ActiveState offers a free and ready-to-install Perl distribution for Windows, Mac, OS X, Linux, Solaris, AIX, and HP-UX.
  • IBM® trial software: Build your next development project with software for download directly from developerWorks.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into AIX and Unix on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=AIX and UNIX
ArticleID=261807
ArticleTitle=Learn the Perl/Tk module, Part 1: The basics of Perl/Tk
publish-date=10162007