Hi Saif,
Thank you for providing runnable code! But I am still not sure exactly what you are trying to achieve?
I think you "short-sell" pack(). This the most commonly used geometry manager. The more complex ones like grid() are less commonly used. I have never used Canvas.
When using pack(), you need to think about packing Frames within Frames. Think of a Frame as a widget unto itself. The most common mistake when using pack() is to not use enough Frames.
In the below code, I did have trouble getting the required minimum amount of "blank violet colored space" on the screen. But I haven't coded an Tk in a long time. The main idea with pack, is that if you want your list box to have some indentation from the left, or perhaps to center it on the screen, make a Frame which contains a "dummy" spacer frame, then your Listbox and pack appropriately (often when using enough frames, the default pack will be fine).
When using pack() with some complicated GUI object that needs multiple widgets to "line up" in a vertical sense, get that working say in simple main window Frame on the left hand side of the screen. Then instead of using the mainWindow, put that stuff into a separate Frame and pack that Frame probably within a Frame within the mainWindow.
#!/usr/bin/perl
use strict;
use Tk;
my $mw = MainWindow->new;
#$mw->geometry('400x250'); #some issues with this...
#see my post
my $FirstFrame = $mw->Frame(
-bg => 'lavender',
-relief => 'sunken',
-width => 400,
-height => 250)->pack(-expand => 1, -fill => 'both');
my $spacer_frame = $FirstFrame->Frame(
-width =>10, # ADJUST THIS TO SEE WHAT IT DOES
)->pack(-side => 'left');
my $listbox = $FirstFrame->Scrolled ('Listbox',
-bg => 'white',
-scrollbars => "e",
-selectmode => 'extended',
-width => 10,
-height => 5, )->pack(-side=>'left');
my @strings2 = qw/apples bananas pears grapes/ x 5;
$listbox->insert('end',@strings2);
MainLoop();
| [reply] [d/l] |
G'day Marshall,
You asked me two questions about your code (via /msg).
Generally, I'd recommend you actually post these questions; that way, if I'm unavailable, someone else could answer them.
I'll answer the second question first: it applies to the answer to the first question.
"With the geometry statement, I couldn't get the listbox to appear at top of the main frame"
That has nothing to do with geometry().
If you manually resize the GUI, you'll see the Listbox in the centre of the left-hand side.
Look for -side and -anchor in Tk::pack.
The former defaults to top, you've changed it to left, that's where it appears, all good so far.
The latter defaults to center, you haven't changed that, so it appears in the centre, not what you want;
had you changed that to n, it would appear at the top (which is where you want it).
"Maybe you can show me how to make my code work as OP intended"
Here's a brief list of changes I made to your code:
-
Shebang: that's just for me; I don't use the system Perl — you possibly don't need this change.
-
Added use warnings; — you should have this near the top of all Perl code.
-
Reinstated $mw->geometry('400x250');.
-
Removed the -width and -height from $FirstFrame.
-
Removed the entire $spacer_frame — see -padx below.
(This might be useful in a more complex GUI, but I considered it unnecessary here.)
-
Multiple changes to $listbox:
-
Widget options -width and -height now use the OP's original, scaled $size values.
(Yes, hard-coded for demo purposes only; but, as I said in my original reply, "generally a bad move".)
-
Added pack() options: -anchor n -padx 50 -pady 12.
See my first answer (above) for an explanation of -anchor.
The -padx and -pady options use the OP's original $location values.
The -padx option handles what the removed $spacer_frame was doing.
Here's the modified code:
#!/usr/bin/env perl
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
$mw->geometry('400x250');
my $FirstFrame = $mw->Frame(
-bg => 'lavender',
-relief => 'sunken',
)->pack(-expand => 1, -fill => 'both');
my $listbox = $FirstFrame->Scrolled('Listbox',
-bg => 'white',
-scrollbars => "e",
-selectmode => 'extended',
-width => 200/7,
-height => 212/15,
)->pack(qw{-side left -anchor n -padx 50 -pady 12});
my @strings2 = qw/apples bananas pears grapes/ x 5;
$listbox->insert('end',@strings2);
MainLoop();
This code now renders exactly the same as the OP's original code.
There is only one difference in functionality that I detected.
If you manually resize the GUI, with this code, the Listbox will also resize;
with the OP's code, the Listbox will be chopped off on the right, at the bottom, or possibly on both of those sides.
In either case, I can still scroll the list with the mousewheel.
So that's a serendipitous improvement.
| [reply] [d/l] [select] |
Hi Brother Marshall
Thank you for that, I am beginning to understand sort of how the hierachy works...so Frames can take subFrames and scrolling listboxes in them...I need a scrolling structure (Frame,Pane, Whatever) to take multiple rows of Checkbuttons which behave as a scrlled item behaves...without leaking out of the parent Frame/Pane etc. But I will try and do as you say. Thank you.
| [reply] |
#!/usr/bin/env perl
use strict;
use warnings;
use constant {
LIST_W => 28,
LIST_H => 14,
LIST_X => 50,
LIST_Y => 12,
};
use Tk;
use Tk::HList;
my $mw = MainWindow->new;
$mw->geometry('400x250');
my $hlist_F = $mw->Frame()->pack(qw{-expand 1 -fill both});
my $hlist_scrl = $hlist_F->Scrolled(HList =>
-scrollbars => 'osoe',
-columns => 1,
-header => 0,
-itemtype => 'window',
-width => LIST_W,
-height => LIST_H,
)->pack(
-fill => 'y',
-side => 'left',
-anchor => 'n',
-padx => LIST_X,
-pady => LIST_Y,
-ipadx => 5,
-ipady => 5,
);
my $hlist = $hlist_scrl->Subwidget('scrolled');
my @colours = qw{
red green blue yellow cyan magenta orange teal purple
pink lime azure rose olive lilac
black grey white gold silver bronze
};
my (%palette, @cboxes);
for (@colours) {
$palette{$_}{val} = 0;
$palette{$_}{cb} = $hlist->Checkbutton(
-text => $_,
-variable => \$palette{$_}{val},
-anchor => 'w',
-pady => 0,
);
push @cboxes, $palette{$_}{cb};
}
$hlist->add("$_", -widget => $_) for @cboxes;
MainLoop();
I believe it covers all the bits that you want.
| [reply] [d/l] |