forrest has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing some Perl/Tk code where I want something other than user input to change the visible portion of a Scrolled widget. I've tried something like the following (which doesn't work);
#!/usr/bin/perl -w use strict; use Tk; my $main = MainWindow->new; my $list = $main->Scrolled('Listbox', -scrollbars => 'e', -selectmode => 'single')->pack; foreach my $i (1..100) { $list->insert('end', "item $i"); } my $button = $main->Button(-text => "Scroll to Bottom of List", -command => \&scroll_to_bottom)->pack; MainLoop; sub scroll_to_bottom { my ($first, $last) = $list->Subwidget("yscrollbar")->get; # set to end of list my $winsize = $last - $first; $first = 1.0 - $winsize; $last = 1.0; $list->Subwidget("yscrollbar")->set($first, $last); }
When the button is pressed, The scrollbar jumps to the bottom like I want, but the visible portion of the Listbox stays the same. Playing with the thumb of the scrollbar a little will make the Listbox suddenly jump to the end where I want it.

It seems that when the scrollbar's appearance is updated, its callback (which would adjust the position of the widget it's controlling) isn't called.

I'm hoping I won't have to do my own custom scrollbar to get this functionality; the standard Scrolled is really close.

Does anyone know how I can make this work?

Replies are listed 'Best First'.
Re: Invoking scrolling externally on a Perl/Tk Scrolled widget
by pg (Canon) on Nov 30, 2003 at 03:17 UTC

    It is much simpler than this. The see() method of Listbox allows you to scroll a particular list element into the "view".

    use strict; use Tk; my $main = MainWindow->new; my $list = $main->Scrolled('Listbox', -scrollbars => 'e', -selectmode => 'single')->pack; foreach my $i (1..100) { $list->insert('end', "item $i"); } my $button = $main->Button(-text => "Scroll to Bottom of List", -command => \&scroll_to_bottom)->pack; MainLoop; sub scroll_to_bottom { $list->see('end');#make the last element viewable }
      Oh, that's cool.

      I found another solution: if I replace

      $list->Subwidget("yscrollbar")->set($first, $last);
      with
      $list->yviewMoveto($first);
      it works.
        Hey, I am glad to see I am not the only one who is interested in achieving this. However I want to be able to scroll to a certain line number and have the cursor be flashing at the beginning of the line I want to scroll to. I am using Text instead of ListBox though. Anyone have any ideas?