You've already seen the purpose of the pack method. The name of the game is "geometry management," the art of arranging widgets on the screen and specifying a policy for rearranging themselves when the screen is resized. Tk supports three types of geometry managers: placer, packer, and grid. The placer is the simplest of the lot. Like Motif's Bulletin Board widget or Visual Basic's geometry management policy, you have to specify the x and y coordinates of each widget. I'll just refer you to the Tk documentation for more details on the placer.
The packer, like Motif's Form widget, is a powerful constraint-based geometry manager. The packer is not an object; it is simply the algorithm implemented by the pack() method. In other words, the call $widget->pack() is a request to the widget to pack itself in the next available space inside its containing widget.
When you pack a suitcase, you typically start at one end and, for every item, proceed to fill in the remaining space. The packer works exactly like this, but there's one crucial difference. Once it sticks a widget onto an edge of a container widget, it slices off that entire edge and takes it off the remaining available space. Figure 14.10 illustrates the packing algorithm.
In this figure, if the
You can use pack to accomplish three things:
You might be wondering how to insert three widgets on the left side (as shown in Figure 14.11 ) if the first widget to be inserted takes over the entire side.
The only way to solve this problem is to create a frame widget and stick it in the left side of the top window. Since a frame is a container for other widgets, these three widgets can be packed inside this frame, as shown in the following code:
$frame->pack(-side => 'left', -fill => 'y', -expand => 'y'); # Now create buttons b1, b2 and b3 as children of frame, and # pack top to bottom $b1 = $frame->Button (-text => 'Oh ')->pack(); $b2 = $frame->Button (-text => 'Hello')->pack(); $b3 = $frame->Button (-text => 'There')->pack();
pack inserts the widgets from top to bottom, by default.
The grid method tells the widget to use the grid geometry manager. All child widgets within one parent must use the same geometry manager, but you are free to use any geometry manager of your choice for a given combination of a parent and its contained widgets or for widgets nested within each child.
The grid geometry manager allows you to slot widgets in rows and columns, much like HTML's table tag. The maximum width of any widget in a column determines the width of that column, and the height of a row is determined by the maximum height of any widget. This is how you use gridded geometry management:
$button->grid (row => 0, column => 0);
This command puts the button on the top-left corner.
Like HTML's tables, a widget can be made to span any number of rows and columns, using the rowspan and columnspan options. The widget still belongs to the row and column specified by " row " and " column " but straddles the required span of columns and/or rows, as shown in the following example:
$button->grid(row => 1, col => 2, columnspan => 2, sticky => 'ns');
The button in this example straddles two columns but doesn't use up all the space. The