Home > Archive > PerlTk > March 2007 > Scrollable grid
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| ben@jammin.co.uk 2007-02-25, 10:02 pm |
| Hi All,
I'm a real newbie to Perl::Tk and struggling to get widgets working
together as I want them to.
What I'm trying to achieve is quite simple:
I want a window (800x600) with two frames that will remain a fixed
size.
Frame one (800x560) will contain a grid 3 columns(1 button and 2
labels) by ~300 rows, 40px high each. So this frame needs to be
scrollable as obviously there are more rows than can be displayed at
one time. The navigation is done by keyboard so this frame needs to
scroll as widgets that are off screen come into focus.
Frame two (800x40) will just contain some static text.
The solution I have come up with doesn't work:
The main window has two Frames packed into it with the dimensions
above.
The top frame has a canvas widget, becuase it is scrollable, and the
canvas widget contains a frame for each row. Each row is a grid with a
button and two labels.
This doesn't work, I lose the botton frame completely and scrolling
resizes the window into odd and unpredictable shapes.
If I use the canvas->createwindow method for each button and label I
can get the result I'm looking for but these means specifying exact
width and positioning for each window to acheive a grid effect. This
does not seem scaleable.
Anyone have a better approach?
Thanks in advance.
| |
| Ch Lamprecht 2007-02-26, 8:04 am |
| ben@jammin.co.uk wrote:
> Hi All,
>
> I'm a real newbie to Perl::Tk and struggling to get widgets working
> together as I want them to.
>
> What I'm trying to achieve is quite simple:
>
> I want a window (800x600) with two frames that will remain a fixed
> size.
>
> Frame one (800x560) will contain a grid 3 columns(1 button and 2
> labels) by ~300 rows, 40px high each. So this frame needs to be
> scrollable as obviously there are more rows than can be displayed at
> one time. The navigation is done by keyboard so this frame needs to
> scroll as widgets that are off screen come into focus.
>
> Frame two (800x40) will just contain some static text.
>
> The solution I have come up with doesn't work:
>
> The main window has two Frames packed into it with the dimensions
> above.
>
> The top frame has a canvas widget, becuase it is scrollable, and the
> canvas widget contains a frame for each row. Each row is a grid with a
> button and two labels.
> Anyone have a better approach?
Hi,
Take a look at
perldoc Tk::Pane
perldoc Tk::Table
Christoph
--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push@i,Tk::GraphItems->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>another=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])for(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for(@i)});MainLoop
| |
| ben@jammin.co.uk 2007-02-28, 7:03 pm |
| Hi Cristoph,
Thanks for the Tk::Pane tip.
It does exactly what I need it to do, except...
How can I take the screen focus to widget that is outside the scroll
region? With Canvas I was using:
$canvas->configure(-scrollregion =>
[ $canvas->bbox("canvasWindowName")]
);
But this uses tags.
Have you got any ideas?
Thanks in advance.
Ben
| |
| Ch Lamprecht 2007-02-28, 7:03 pm |
| ben@jammin.co.uk wrote:
> Hi Cristoph,
>
> Thanks for the Tk::Pane tip.
>
> It does exactly what I need it to do, except...
>
> How can I take the screen focus to widget that is outside the scroll
> region? With Canvas I was using:
>
Hi,
Tk's standard binding for moving the focus is 'Tab' and 'shift-Tab'.
I added a binding to move the Button with the current focus into the visible area.
See:
perldoc Tk::Pane
Christoph
use strict;
use warnings;
use Tk;
my @buttons;
my $top = tkinit;
my $fr = $top->Scrolled('Pane',
-scrollbars => 'e',
-height => 600,
-width => 560,
)->pack;
for my $i(0..49){
my $new_button = $fr->Button(-text => "Button_$i",
-command => sub{},
)->pack;
push @buttons,$new_button;
$new_button->bind('<FocusIn>',sub{$fr->see($_[0])});
}
$buttons[0]->focus;
MainLoop;
--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push@i,Tk::GraphItems->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>another=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])for(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for(@i)});MainLoop
| |
| Ch Lamprecht 2007-03-01, 4:09 am |
| Ch Lamprecht wrote:
> ben@jammin.co.uk wrote:
>
> Hi,
>
> Tk's standard binding for moving the focus is 'Tab' and 'shift-Tab'.
> I added a binding to move the Button with the current focus into the
> visible area.
> See:
>
> perldoc Tk::Pane
>
> Christoph
>
>
> use strict;
> use warnings;
> use Tk;
> my @buttons;
>
> my $top = tkinit;
> my $fr = $top->Scrolled('Pane',
> -scrollbars => 'e',
> -height => 600,
> -width => 560,
> )->pack;
A cleaner way: Add a Tag and bind once...
Christoph
for my $i(0..49){
my $new_button = $fr->Button(-text => "Button_$i",
)->pack;
push @buttons,$new_button;
$new_button->AddBindTag('PaneItem');
}
$fr->bind('PaneItem','<FocusIn>',\&see_item);
$buttons[0]->focus;
MainLoop;
sub see_item{
$fr->see($_[0]);
}
--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push@i,Tk::GraphItems->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>another=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])for(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for(@i)});MainLoop
| |
| ben@jammin.co.uk 2007-03-02, 8:03 am |
| Hi Christoph,
That's brilliant, thanks!
I have noticed that the see() method only seems to work if I have
specified scrollbars. Ideally I don't want to show any scrollbars I
just want the pane to scroll as the focus moves down. Do you know a
way to make that work?
Thanks again.
Ben
| |
| Ch Lamprecht 2007-03-02, 8:03 am |
| ben@jammin.co.uk wrote:
> Hi Christoph,
>
> That's brilliant, thanks!
>
> I have noticed that the see() method only seems to work if I have
> specified scrollbars. Ideally I don't want to show any scrollbars I
> just want the pane to scroll as the focus moves down. Do you know a
> way to make that work?
A quick hack would be to packForget the scrollbar after initialization like below.
It might be cleaner to make the Pane scrollable setting up scrollcommands as
needed 'by hand' instead of calling 'Scrolled'.
Christoph
use strict;
use warnings;
use Tk;
my @buttons;
use Data::Dumper;
my $top = tkinit;
my $fr = $top->Scrolled('Pane',
-scrollbars => 'e',
-height => 600,
-width => 560,
)->pack;
$fr->Subwidget($_)->packForget for qw/yscrollbar corner/;
for my $i(0..49){
my $new_button = $fr->Button(-text => "Button_$i",
)->pack;
push @buttons,$new_button;
$new_button->AddBindTag('PaneItem');
}
$fr->bind('PaneItem','<FocusIn>',\&see_item);
$buttons[0]->focus;
MainLoop;
sub see_item{
$fr->see($_[0]);
}
--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push@i,Tk::GraphItems->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>another=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])for(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for(@i)});MainLoop
| |
| ben@jammin.co.uk 2007-03-04, 7:03 pm |
| Hi Cristoph,
That's brilliant now. Thank you. I may have to ask you some more
questions soon if you don't mind. Thanks again!
Ben
|
|
|
|
|