Home > Perl > GUI Applications in Perl > Writing GUI Applications using Perl/Tk - Part 3
Writing GUI Applications using Perl/Tk - Part 3
Written by Philip L Yuson   

Who is this for

For those who want to have a idea on how composite widgets are created in Perl/Tk.

What you should know

Basic Perl programming, how to create widgets and define their options using Perl/Tk. Perl Object Oriented (OO) concepts will help a lot. But if you are not familiar with Perl OO concepts, you can still understand this.


Creating widgets in Perl/Tk can be intimidating at first glance. However, once you get an idea of how it works, you will in fact, find it quite interesting.

A composite widget is made up of several other widgets. An example of this is a ComboBox. The ComboBox is not a standard Tk widget. So we will try to make one (or at least present a skeleton on how to make one).

What you have to decide in making a composite widget is the type of widgets you will need. For a ComboBox, you will need an Entry, an arrow button and of course a ListBox where you will store the list of items in the ComboBox.

Since we want to enclose these three widgets in a frame, we can use the Frame widget as the base widget. This means that your composite widget can use the options and methods in the Frame widget. This also saves you the time of defining a Frame widget within the ComboBox.

All widgets are defined in a package. The package defines our base widgets and also the methods and options for this new widget.

Let us Begin

We define our package by giving it a name. Since this package is part of the Tk package, we need define this widget with a Tk prefix like so:

package Tk::pyCombo; # I will call it pyCombo for my sake.

Next, we have to define the widgets that we need. In our case, we need the Derived and Frame widgets:

require Tk::Derived;
require Tk::Frame;

Perl uses an array called @ISA where you can specify the base widgets. You can set the value of the @ISA variable through:

@ISA = qw(Tk::Derived Tk::Frame);

Now, we tell Perl to accept the name of this widget:

Construct Tk::Widget 'pyCombo';

Widget Methods

Initialization takes place in the Populate subroutine. This subroutine is called when you define a new widget.

Populate is where you perform your initialization routines. You will now create an Entry widget. Your arrow button will be a Label widget. The reason for this is that using a Button widget will not look nice as the Button widget has a greater height than the Entry widget. You will also define the bindings of the Entry and Label widgets. Bindings allow you to associate a subroutine to an event within the widget.

Sub Populate {

# get parms: widget and other arguments

my ($cw, $arg) = @_;

#Populate parent widgets


# Include these options in the widget


-listheight=>[qw/PASSIVE listheight ListHeight, 5/],

-textwidth=>[qw/PASSIVE textwidth TextWidth, 10/],

-items=>[qw/PASSIVE items Items/, []]);

. . . (other statements here) . . .


The ConfigSpecs method allows you to define options for your widget. In the example, we defined three options: -listheight, -textwidth and -items. The first item in the array passed to the option defines where to apply the configuration. PASSIVE means that you simply store the value. The second item defines the name of the widget in the Tk database. The third item defines the class of the widget in the Tk database. The last item is the default value of the option.

Once an option is defined via ConfigSpec, you can access it using the configureor cget methods.

You will also be defining your bindings in this subroutine. One of your bindings will execute a routine that displays the ListBox when the Label (Arrow) widget is clicked.

You can also define subroutines that allow you to manipulate your widget.

Testing the Widget

You can test the widget by appending the main routine at end of your package. You do this by specifying that the next instructions will be in the main package:

package main;
#Define New Window
my $m = new MainWindow;

#If Main Window is closed then terminate program
$m->bind("", sub { exit } );

#Define a ComboBox and specify the items
my $c = $m->pyCombo(
-items=>[qw/one two three four five]);

#Place the combo box

# Call MainLoop to display and process the window

You can read more on this in the Perl/Tk FAQ.
If you have a Postscript reader plus tar and gunzip programs, you can download the Pocket Reference and print it out.
Finally, you can also download the full source of the ConceptCombo widget from my website.

You may also want to look at other widgets I have created: ConceptGrid and ConceptMask. Go to my WidgetsPage.

My most recent article(s) that
you might also find interesting:

Copyright: © 2018 Philip Yuson