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

I've managed to write a working widget with a Listbox. But I cannot find a way to Scroll the Listbox within the widget. (Search for 'Scrolled') See these two pieces of code and lines.

Scenario

perl testPicker.pl

HELP!!!

testPicker.pl

#!/usr/bin/perl -w use Tk; use Picker; use strict; my $mw= MainWindow->new; my $ep= $mw->Picker(-title=> 'Entity Picker'); # should return an entity key my $choice= $ep->Show; print "$choice\n"; $mw->destroy; MainLoop;

Picker.pm is

$Tk::Picker::VERSION= '1.0'; package Tk::Picker; use Tk::Listbox; use base qw/Tk::Derived Tk::DialogBox/; use subs qw/build/; use strict; Construct Tk::Widget 'Picker'; # Class global variables sub build($); # Class initializer. sub ClassInit($$) { my ($class, $mw)= @_; $class->SUPER::ClassInit($mw); return 1; } our @fields= ( qw/ AUSTIN AUTUN AVA AVERY AYDEN BAILEY BENJAMIN BENNY BIANCA BILLIE BILLY BLAKE BRADEN BRADLEY BRADY BRANDON BRAYDEN BREANNA BRENDAN BRIAN BRIANA BRIANNA BRITTANY BRODY BROOKE BROOKLYN BRYAN BRYCE BRYSON CADEN CAITLIN CAITLYN CALEB CAMERON CAILA CARLOS CAROL CAROLINE CARSON CARTER CASSANDRA CASSIDY CATHERINE CESAR CHARLES CHARLOTTE CHASE CHELSEA CHEYENNE CHLOE CHRISTIAN CHRISTINA CHRISTOPHER CLAIRE CODY COLBY COLE COLIN COLLIN COLTON CONNER CONNOR COOPER COURTNEY CRISTIAN CRYSTAL DAISY DAKOTA DALTON DAMIAN DANIEL DANIELA DANIELLE DAVID DELANEY DEREK DESTINY DEVIN DEVON / ); sub Populate($$) { my ($self, $args)= @_; $args->{'-buttons'} = ['Cancel', 'Select' ] unless defined $args->{'-buttons'}; $self->SUPER::Populate($args); $self->build; } # subroutines sub build($); sub buttonPress($$) { my ($self, $param)= @_; print "$param\n"; push @fields, "Name" . $#fields; $self->build; } sub build($) { my ($self)= @_; $self->title("My Picker"); $self->Component('Label', 'label1', -text=>"Select a name", -background=>"lightblue")->pack; # how to make a scrolled Listbox??? # does not compile... # So - shouldn't Component accept a nested Component somehow?? # my $sbox= $self->Component('Scrolled', 'scroll', # $self->Component('Listbox', 'sbox', # -selectmode=>'single', # -font=>'ansifixed', # -width=>20, # -height=>15, # ), # -scrollbars=>'osoe' # )->pack; # an unscrolled Listbox my $lbox= $self->Component('Listbox', 'lbox', -selectmode=>'single', -font=>'ansifixed', -width=>20, -height=>15, )->pack; $lbox->insert('end', @fields); $self->{lbox}= $lbox; } sub Show($) { my ($self)= @_; $self->Popup; $self->waitVariable(\$self->{'selected_button'}); return 'Cancel' if ($self->{'selected_button'} eq 'Cancel'); my $cvalue= $self->{lbox}->curselection; return 'No selection' if ($#$cvalue < 0); return $fields[$cvalue->[0]]; } 1;

Replies are listed 'Best First'.
Re: Widget with Scrolled Listbox
by james28909 (Deacon) on Apr 11, 2016 at 06:55 UTC

      Thanks for your reply - but - I already know how to construct a scrolled Listbox with its callback function, etc. And I have a sophisticated system working, except for this detail.

      I'd like to construct a widget in the form of a popup window that can be called as a dialog box containing a scrolled Listbox.

      Chapter 14 of the Mastering book explains how to construct a widget. It rests on the Construct operation, followed by a Component call. This appears to be a macro generator, but it's hard to tell, since the Perl debugger refuses to follow the operation. Component seems to work fine for a Listbox, but I do not see how to use it to construct a Scrolled Listbox.

      If you look at my example, lines 79-87 in principle should replace lines 89-94, but it will not compile. The example works very well without the Scrolled feature, and I've tried lots of variations on that plan with no success.

      Comes down to poor documentation of Construct and Component. Someone obviously knows how to make great widgets. Why can't I?

        sub build($) { my ($self)= @_; $self->title("My Picker"); $self->Component('Label', 'label1', -text=>"Select a name", -background=>"lightblue")->pack; my $lbox= $self->Scrolled("Listbox", -scrollbars => 'oe')->pack; $lbox->insert('end', @fields); $self->{lbox}= $lbox; }

        Why create a sub class at all? The code posted so far, from the class name, to the @fields array, hints heavily against a sub class being necessary

        Also "Scrolled" is not a type of widget/class, its a helper method

        Use Tk::WidgetDump to see what see sub Tk::Widget::Scrolled and sub Tk::Frame::AddScrollbars actually do, what widgets they create