perltk-toolkittkx

Loop to define buttons in Perl / Tkx


I am trying to define a sequences of buttons in Perl with Tkx through a loop; the text and actions of each button is defined in an array of hash tables.

However, no matter what button I click on only the action of the last button is triggered.

This is the code I use.

use strict;
use Tkx;

my @Buttons = (
    { 'descr'=> "Button #0", 'cmd'=> sub { print "TODO: to implement (button #0)\n\n"; } },
    { 'descr'=> "Button #1", 'cmd'=> sub { print "TODO: to implement (button #1)\n\n"; } }
);

my %Widg;
$Widg{"."}= Tkx::widget->new(".");
$Widg{"."}->g_wm_title("List of buttons"); 
$Widg{"."}->g_wm_minsize(350, 300);

Tkx::font_create("H4", -family => "Helvetica", -size => 8);

$Widg{".fButton"} = $Widg{"."}->new_ttk__frame( -padding => "2 2 5 5");
$Widg{".fButton"}->g_grid(-row => 1, -sticky => "w");

my $id=-1;
foreach my $rh_measure (@Buttons) {
    ++$id;
    $Widg{".fButton.bRun$id"}=$Widg{".fButton"}->new_ttk__button(-text => $rh_measure->{'descr'}, -command => sub { &wrapper($id); });
    $Widg{".fButton.bRun$id"}->g_grid( -row => $id, -column => 1, -sticky => "w");
} 

Tkx::MainLoop;


sub wrapper {
    my $id=shift;
    print "Process command for button #$id\n";
    &{$Buttons[$id]->{'cmd'}}();
}

Solution

  • Actually, you just have to call the command via reference and the argument not being referenced.

    $Widg{".fButton.bRun$id"}=$Widg{".fButton"}->new_ttk__button(-text => $rh_measure->{'descr'}, -command => [\&wrapper, $id]);