•Re: Tk::pack help
by merlyn (Sage) on Aug 03, 2004 at 19:28 UTC
|
| [reply] |
|
|
The rest of my GUI is a pack geometry. how can i mix pack and grid?
| [reply] |
|
|
You don't. You pack a frame, then put a grid inside the frame. Then you can pack the combined frame with the rest of the items in the outer window/frame.
| [reply] |
Re: Tk::pack help
by davidj (Priest) on Aug 03, 2004 at 19:35 UTC
|
You could do it with pack by putting cells A and C in a frame (and ->pack(-side=>'top') and cells B and D in a frame (and ->pack(-side=>'top'). Then the frames you would ->pack(-side=>'left').
That being said, merlyn is right. The grid geometry manager is better suited for such a layout.
davidj | [reply] [d/l] [select] |
|
|
The problem with the nested frames is that the widgets won't necessarily be aligned in the other direction. Hence, the grid manager.
| [reply] |
|
|
You are correct about that. However, before I was turned on to the grid and form geometry managers, I was able (with some difficulty and complexity) to get fairly decent grid layouts using pack. By all means, it is not the way to go and grid/form are the best options.
davidj
| [reply] |
Re: Tk::pack help
by sleepingsquirrel (Chaplain) on Aug 03, 2004 at 20:25 UTC
|
#!/usr/bin/perl -w
use strict;
use Tk;
my $mw = MainWindow->new;
my $top_frame = $mw->Frame()->pack(-side => "top");
my $bot_frame = $mw->Frame()->pack(-side => "top");
$top_frame->Button(-text => "A",)->pack(-side => "left");
$top_frame->Button(-text => "B",)->pack(-side => "left");
$bot_frame->Button(-text => "C",)->pack(-side => "left");
$bot_frame->Button(-text => "D",)->pack(-side => "left");
MainLoop;
-- All code is 100% tested and functional unless otherwise noted.
| [reply] [d/l] |
|
|
Maybe closer to your needs...
#!/usr/bin/perl -w
use strict;
use Tk;
my $mw = MainWindow->new;
for (["A","B"],["C","D"],["E","F"],["G","H"])
{
my $frame = $mw->Frame()->pack(-side => "top");
$frame->Button(-text => "$_->[0]",)->pack(-side => "left");
$frame->Button(-text => "$_->[1]",)->pack(-side => "left");
}
MainLoop;
-- All code is 100% tested and functional unless otherwise noted.
| [reply] [d/l] |
Re: Tk::pack help
by rinceWind (Monsignor) on Aug 04, 2004 at 09:31 UTC
|
Others (Randal especially) are right about grid being a more suitable geometry manager. There is nothing to stop you from putting a frame inside a grid cell, and then using pack as the geometry manager for the frame.
I tend to use grid cells for columns that I want to line up, and frames with pack if a cell needs to contain multiple items that don't line up (with anything outside the cell).
As an example of getting the best out of grid, see the RPN calculator tutorial on the Tk wiki.
-- I'm Not Just Another Perl Hacker
| [reply] |
Re: Tk::pack help
by Elderian (Sexton) on Aug 05, 2004 at 06:00 UTC
|
Heya,
i played around a little bit with pack, but it seems to be impossible with a single pack.
I could imagine to ways of solving it:
1. As some monks already mentioned, grid would be the geometry manager, which is most suitable for this task.
2. Untested: If it is possible to insert a frame into a frame, you could try the following code:
my $topframe = $mainWindow->Frame;
$topframe->pack(-expand => 'x', -fill => 1);
my $leftframe = $topframe->Frame;
$leftframe->pack(-side => 'left', -expand => 'x', -fill =>1);
my $rightframe = $topframe->Frame;
$rightframe->pack(-side => 'left', -expand => 'x', -fill =>1);
... but using grid is much easier to and to understand.
Elderian | [reply] [d/l] [select] |
|
|
With this approach vertical alignment of the widgets in the frames could be difficult.
Here's a hack to use pack() with helper frames to form a gridded structure.
#!/usr/bin/perl
use strict;
use List::Util qw(max);
use POSIX qw(ceil);
use Tk;
my $mw = new MainWindow();
my @fields = ("Name", "Street", "Postal code", "City");
my @l;
for (@fields) {
my $f = $mw->Frame->pack(-fill => "x");
my $l = $f->Label(-text => $_, -anchor => "w")->pack(-side => "lef
+t");
push @l, $l;
my $e = $f->Entry->pack;
}
my $maxwidth = max map { $_->reqwidth } @l;
my $fontwidth0 = $mw->fontMeasure($l[0]->cget("-font"), "0");
my $maxwidth_chars = ceil($maxwidth / $fontwidth0);
for (@l) {
$_->configure(-width => $maxwidth_chars);
}
MainLoop;
The hack is to set the -width option of the labels to get a uniform width for the left column. In the sample script above this is done dynamically by extracting the width of the largest label. Unfortunately specification of widths is done in characters, but the reqwidth() method returns pixels, so an additional conversion is necessary.
| [reply] [d/l] |