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

I'm using the following subroutine to generate an 'x' amount of anonymous widgets based upon user input. The script works fine, if I enter in 5 it produces 5. My question is how do I retrieve the value of each new anonymous Entry widget when it has no variable name? Here's my sub routine.....any ideas on how to better set this up?
sub aaa { $count = 1; while($count <= $entry_amount->get) { $label_g = $count_g; $button_b = $count_b; $_ = $mw->Frame()->pack(-side=>top); $_->Label(-text=>"Variable")->pack(-side=>left, -padx=>5, -pad +y=>5); $_->Entry(-width=>30)->pack(-side=>left, -padx=>5, -pady=>5); $mw->update; $count++; } }

Replies are listed 'Best First'.
Re: Perl/Tk and anonymous widgets
by Roy Johnson (Monsignor) on Oct 10, 2005 at 19:56 UTC
    A more Perlish way of writing that would be
    sub aaa { map { my $new_widget = $mw->Frame()->pack(-side=>top); $new_widget->Label(-text=>"Variable")->pack(-side=>left, -padx=> +5, -pady=>5); $new_widget->Entry(-width=>30)->pack(-side=>left, -padx=>5, -pad +y=>5); $mw->update; $new_widget; } 1 .. $entry_amount->get; }
    Now the sub returns a list of widgets.

    Caution: Contents may have been coded under pressure.
Re: Perl/Tk and anonymous widgets
by chester (Hermit) on Oct 10, 2005 at 19:50 UTC
    If you want to store an unknown number of things, an array is always a good place to look first. So push the Entries into an array as you create them (or use a hash, or write a class that has an Entry as an instance variable and then store an array of those objects, or some other way).
Re: Perl/Tk and anonymous widgets
by rcseege (Pilgrim) on Oct 11, 2005 at 02:33 UTC

    Another thing you can do is to take advantage of the fact that all the entries are children of the same frame and use the $widget->children method to list all the frame's children, then iterate through and extract the contents from each Entry.

    Here's one example of how this might be done:
    use strict; use warnings; use Tk; my $mw = MainWindow->new; my $top = $mw->Frame->pack(-side => 'top'); my $bottom = $mw->Frame->pack(-side => 'top'); my $entryCount = $top->Entry( -width => 2 )->pack(-side => 'left'); $top->Button( -text => "Create Entries", -command => [\&createEntries, $entryCount, $bottom] )->pack(-side => 'left'); $top->Button( -text => "Print Contents", -command => [\&printContents, $bottom] )->pack; MainLoop; sub createEntries { my ($entry, $frame) = @_; my $count = $entry->get(); return unless $count && $count =~ /^\d+$/; foreach my $row (1 .. $count) { $frame->Label( -text => "Entry $row:", -anchor => 'w' )->grid( $frame->Entry(-width => 20) ); } } sub printContents { my $frame = shift; my $count = 1; foreach my $w ($frame->children) { printf "Entry %d: %s\n", $count++, $w->get() if ref($w) eq 'Tk::Entry'; $w->destroy; } print "\n"; }

    --Rob

Re: Perl/Tk and anonymous widgets
by zentara (Cardinal) on Oct 11, 2005 at 10:53 UTC
    I always use hashes to store names for the anonymous widgets, making them "non-anonymous" :-) It seems messier at first, but it makes it very easy to access any widget. As a bonus, you have it setup as a hash to make placing it into a package or module easier.
    my %hash; # to store all the widgets in sub aaa { $count = 1; while($count <= $entry_amount->get) { $label_g = $count_g; $button_b = $count_b; $hash{$count}{'frame'} = $mw->Frame() ->pack(-side=>top); $hash{$count}{'label'} = $hash{$count}{'frame'}->Label(-text=>"Variable") ->pack(-side=>left, -padx=>5, -pady=>5); $hash{$count}{'entry'} = $hash{$count}{'frame'}->Entry(-width=>30) ->pack(-side=>left, -padx=>5, -pady=>5); $mw->update; $count++; } }

    I'm not really a human, but I play one on earth. flash japh