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

Suppose we have multiple Tk buttons. And in -command of each one,the button needs to know wich one it is. A certain -text featuring a unique number for each button can be set when creating them,and then it can be used again by doing something like my $self = shift;   my $ label = $self->cget('-text'); and then one can process $label in the manner needed so that he gets the unique number described above and then proceeding according to that number. Is there another way that one can store information in a button ? How can one get the name of the button from inside the -command subroutine.

Replies are listed 'Best First'.
Re: a Tk object who knows who he is ?
by liverpole (Monsignor) on Aug 21, 2007 at 15:45 UTC
    Hi spx2,

    If I'm following you correctly, what you want is something like this:

    #!/usr/bin/perl -w use strict; use warnings; use Tk; # User-defined my @button_names = qw( blue red green white purple orange ); # Main program my $mw = new MainWindow(-title => 'Button example'); my $fr = $mw->Frame()->pack(-fill => 'x'); foreach my $name (@button_names) { my $b = $fr->Button(-text => $name, -bg => $name)->pack(-side => ' +left'); $b->configure(-command => sub { invoke_button($b, $name) }); } MainLoop; + # Subroutines sub invoke_button { my ($button, $name) = @_; print "You clicked on button '$name'; object is '$button'\n"; }

    The trick is that you create the button first, and then configure it to use a callback which is passed a reference to the button itself.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      yes you're followin correctly. it's also as the approach I thought of...using a closure. thank you

Re: a Tk object who knows who he is ?
by zentara (Cardinal) on Aug 21, 2007 at 16:30 UTC
    Another trick to use, is to stick all the buttons in a hash. The nice thing about that way, is that you can easily perform operations on the buttons from another place in the script (without having to walk the widget's descendents tree). For example:
    #!/usr/bin/perl -w use strict; use warnings; use Tk; my %b; #hash to hold button names my @button_names = qw( blue red green white purple orange ); my $mw = new MainWindow(-title => 'Another Button example'); my $fr = $mw->Frame()->pack(-fill => 'x'); foreach my $name (@button_names) { $b{$name} = $fr->Button(-text => $name, -bg => $name, -command => sub{ print "You clicked on $b{$name} which is ", $b{$name}->cget(-bg),"\n " }, )->pack(-side => 'left'); } $mw->after(5000, sub{ foreach my $button (keys %b){ if($button eq 'red'){next} $b{$button}->configure(-bg => 'grey'); } }); MainLoop;

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum