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

I'm using Perl/Tk. Excellent! Now the problem. I've got a pair of list boxes that I'd like to scroll together (use one scroll bar to control both list boxes which have the same number of entries). In looking over _Perl in a Nutshell_, I see that one can build up a list box and a single scroll bar (page 577).
$scrollbar = $mw->Scrollbar(-orient => 'vertical'); $listbox = $mw->Listbox (-yscrollcommand => ['set' => $scrollbar]); $scrollbar->configure(-command => ['yview' => $listbox]); ...pack stuff...
According to the text, this works quite well. Now for the difficult part. Can the Scrollbar's command execute more than one routine? I'd like to do:
$scrollbar->configure(-command => ['yview' => $listboxA, 'yview' => $l +istboxB]);
and have the callback routine execute TWO routines, one for $listboxA and another for $listboxB. In my searching of the code (Perl/Tk), I can't see if it "walks" the list given for the command to get all of the entries, or just picks the first one and goes from there. The alternative would be to build my own routine that would do the two scrolls, but I was thinking it would be simpler to see if something was already implemented. Thanks for the wisdom! Update: Well, I went out and bought (my company did) the book Mastering Perl/Tk. Followed the example and got it to work. The biggest problem was that the original list boxes had horizontal as well as vertical scrolling. I wanted the horizontal scrolling to stay the way it was. In order to do all of this, I needed to build up the individual list boxes in a couple of frames. It turns out that as nice as it might be, if I tried the 'scrolled' method to just get an X scroll bar on the list box, and tried to atach my own Y scroll bar to both of the list boxes it didn't work. I also found out that the 'Scrolled' method allows for a '-title' which the normal list box doesn't (not very clear in the documentation). Everything is worked out, and I built it as:
Frame1 (title) List_box_1 X_scroll_bar Frame2 (title) List_box_1 X_scroll_bar Y_scroll_bar (links to List_box_1, List_box_2)
Thanks for the help. The pointers were invaluable!

Replies are listed 'Best First'.
Re: Double Callbacks?
by ikegami (Patriarch) on Feb 08, 2007 at 22:20 UTC
    Would something like the following work?
    { package MyYViewMultiplexer; sub new { my $class = shift(@_); return bless([ @_ ], $class); } sub yview { my $self = shift(@_); $_->yview(@_) for @$self; } } $scrollbar->configure(-command => [ 'yview' => MyYViewMultiplexer->new($listboxA, $listboxB) ]);

    Of course, that's a hack. The normal way is to have one list with two fields.

Re: Double Callbacks?
by johngg (Canon) on Feb 08, 2007 at 23:18 UTC
    There's an example of this in Mastering Perl/Tk (O'Reilly - Steve Lidie & Nancy Walsh) on pages 146-148. Boiling it down, you create the scrollbar then you create an anonymous array of listboxes

    my $scrollbar = $mw->Scrollbar(-orient => 'vertical); my $raListboxes = [ $mw->Listbox(), $mw->Listbox() ];

    Then you create a subroutine that will do the scrolling

    sub scrollListboxes { my ($scrollbar, $scrolled, $raListboxes, @args) = @_; $scrollbar->set(@args); my ($top, $bottom) = $scrolled->yview(); foreach my $listbox ( @$raListboxes ) { $listbox->yviewMoveto($top); } }

    then configure each listbox to call the routine and configure the scrollbar to scroll each listbox.

    foreach my $listbox ( @$raListboxes ) { $listbox->configure( -yscrollcomand => [ \&scrollListboxes, $scrollbar, $listbox, $raListboxes ]); } $scrollbar->configure( -command => sub { foreach my $listbox ( @$raListboxes ) { $listbox->yview(@_); } });

    Having set all that up you pack the widgets and away you go. I have not used this code but remembered seeing the example when I saw your post.

    I hope this is of use.

    Cheers,

    JohnGG

    Update: Corrected missing comma in 2nd line of code, thanks ikegami

Re: Double Callbacks?
by zentara (Cardinal) on Feb 09, 2007 at 12:13 UTC