in reply to Re^4: how can i create a scrollbar in the main window using perl tk
in thread how can i create a scrollbar in the main window using perl tk

If you want to control the bindings of your scrollbars manually, it is a PITA full of details. Here is a decent example
#!/usr/bin/perl use strict; use warnings; use Tk; use Tk::Scrollbar; use Tk::Text; our ($textL, $textR, $yscroll, $xscrollleft, $xscrollright); my $main = Tk::MainWindow->new(); my $topframe = $main->Frame()->pack(); my $topleftframe = $topframe->Frame()->pack(-side => 'left'); my $toprightframe = $topframe->Frame()->pack(-side => 'left'); # Left again, because the yscroll is actually going on the right # and putting right here would put yscroll in the middle # Create left Text widget... $textL= $topleftframe->Text(-wrap => 'none' )->pack( -expand => 1, -fill => 'both', ); # Create right Text Widget... $textR = $toprightframe->Text(-width=>'20', -wrap => 'none' )->pack( -expand => 1, -fill => 'both', ); #################################### # scrollbars #################################### # Setup vertical scroll bar for both text windows $yscroll = $topframe->Scrollbar()->pack( -fill => 'y', -side => 'right', ); # Setup two individual horizontal scroll bars for the text windows $xscrollleft = $topleftframe->Scrollbar( -orient=>'horizontal', )->pack( -fill => 'x', -side => 'bottom', -expand => 1, ); $xscrollright = $toprightframe->Scrollbar( -orient=>'horizontal', )->pack( -fill => 'x', -side => 'bottom', -expand => 1, ); # Connect scrollbars to text widgets (and back again)... $xscrollright ->configure( -command => [ \&xscroll_right, $xscrollright, $textR]); $xscrollleft ->configure( -command => [ \&xscroll_left, $xscrollleft, $textL]); $yscroll->configure( -command => [ \&scroll_both, $yscroll, [$te +xtL, $textR]]); $textL ->configure( -yscrollcommand => [ \&set_yscroll ]); $textR ->configure( -yscrollcommand => [ \&set_yscroll ]); $textL ->configure( -xscrollcommand => [ 'set', $xscrollleft]); $textR ->configure( -xscrollcommand => [ 'set', $xscrollright]); # Load some data into them (FOR TESTING ONLY) insert_data(); MainLoop(); # This handles updating yscroll, and making sure both the text # boxes are sync'ed when one of them scrolls via the cursor keys sub set_yscroll { $yscroll->set(@_); foreach my $w ($textL, $textR) { $w->yviewMoveto($_[0]); } } sub scroll_both { my ($sb,$wigs,@args) = @_; my $w; foreach $w (@$wigs) { $w->yview(@args); } } sub xscroll_right { my ($sb,$w,@args) = @_; $w->xview(@args); } sub xscroll_left { my ($sb,$w,@args) = @_; $w->xview(@args); } sub insert_data { my $testdata = <<'EOTESTDATA'; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 EOTESTDATA $textL->insert('end', $testdata); $textR->insert('end', $testdata); }

However, if you don't need the same scrollbar linking multiple widgets, you usually just use a scrolled Pane, and add frames to the scrolled Pane, then addwhatever you want to the Frames. Like:

#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Pane; my $mw = tkinit; my $spane = $mw->Scrolled('Pane', -scrollbars => 'osoe', -bg => 'blue', )->pack(-expand => 1, -fill => 'both'); # create 2 frames side by side in the pane, and fill with more frames my $lframe = $spane->Frame(-bg=>'red')->pack(-side=>'left',-padx=>3); my $rframe = $spane->Frame(-bg=>'red')->pack(-side=>'right',-padx=>3); my %frames; for(1..100){ $frames{$_}{'frame'} = $lframe->Frame()->pack(-pady => 5 ); $frames{$_}{'label'} = $frames{$_}{'frame'}->Label(-text=>'Frame '.$ +_)->pack; my $num = $_; $frames{$_}{'button'} = $frames{$_}{'frame'}->Button( -text=>'Button '.$_, -command => sub{print "$num pressed\n"}, )->pack; } for(101..200){ $frames{$_}{'frame'} = $rframe->Frame()->pack(-pady => 5 ); $frames{$_}{'label'} = $frames{$_}{'frame'}->Label(-text=>'Frame '.$ +_)->pack; my $num = $_; $frames{$_}{'button'} = $frames{$_}{'frame'}->Button( -text=>'Button '.$_, -command => sub{print "$num pressed\n"}, )->pack; } MainLoop;

I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
Re^6: how can i create a scrollbar in the main window using perl tk
by kapsule (Acolyte) on Dec 19, 2008 at 06:40 UTC
    Thanks a lot..Zentara You always Rock..
      How can I get the focus on the scroll bar, by default?
        It depends on the code example. In the linked-text-widgets example I showed, just put a focus statement right before the MainLoop
        $yscroll->focus; # will bind the up/down arrow keys to the vertical s +crollbar MainLoop();
        In general, you can setup the focus order, but it can be a bit tricky. For instance the following allows you to tab around the 3 scrollbars, but the order is not as expected, the $xscrollright gets default since it was the last widget created....so you may need to play around with the order in which the scrollbars are created/packed, and the focus statements.
        $xscrollleft->focus; $xscrollright->focus; $yscroll->focus; MainLoop();
        here is a little example on forcing focus order( as usual, search groups.google.com for more examples)
        #!/usr/bin/perl use Tk; use strict; use warnings; #changes focus on ANY key BUT tab my $win = MainWindow->new(); $win->Button(-text=>'Other Window',-command=>\&otherwindow)->pack; sub otherwindow { my $otherwin = $win->Toplevel; my $foo = $otherwin->Entry->pack; my $bar = $otherwin->Entry->pack; my $baz = $otherwin->Entry->pack; my $boo = $otherwin->Entry->pack; my $baa = $otherwin->Entry->pack; &defineOrder($foo,$baa,$bar,$boo,$baz); } sub defineOrder { my $widget; for (my $i=0; defined( $_[$i+1] ); $i++) { # $_[$i]->bind('<Tab>', [\&focus, $_[$i+1]]); $_[$i]->bind('<Any-KeyPress>', [\&focus, $_[$i+1]]); } # Uncomment this line if you want to wrap around #$_[$#_]->bind('<Key-Return>', [\&focus, $_[0]]); $_[0]->focus; } sub focus { my ($tk, $self) = @_; $self->focus; } MainLoop();

        I'm not really a human, but I play one on earth Remember How Lucky You Are