Search code examples
perlperltk

Can a perl tk widget -command access itself?


I have a perl TK widget which has a -command callback:

my $widget = $mw->Spinbox( -from => -1000, -to => 1000, -increment => 1, -width => 4, -textvariable => $textvariable, -command => sub { ... });

I would like to call a method on the widget inside the command sub.

How can I get a reference to the widget itself inside the callback in a generic way (not by accessing $widget by its name but something generic)?

I have looked into the @_ arguments that get passed into the sub, but they only contain the value of the widget, and the action (e.g. "up"). I was hoping to be able to access the widget via $self or "this" like in javascript.


Solution

  • There are two ways to pass arguments to callbacks:

    1. Use a closure.
    2. Pass an anonymous array containing the callback and the arguments.

    In both the cases, you need to declare the variable containing the widget before you assign the object to it, otherwise it wouldn't be available.

    #!/usr/bin/perl
    use warnings;
    use strict;
    
    use Tk qw{ MainLoop };
    
    my $mw = 'MainWindow'->new();
    
    my $button1;
    $button1 = $mw->Button(-text    => 'Start',
                           -command => sub { $button1->configure(-text => 'Done') }
                          ) ->pack;
    
    my $button2;
    $button2 = $mw->Button(-text    => 'Start',
                           -command => [
                               sub {
                                   my ($button) = @_;
                                   $$button->configure(-text => 'Done');
                               }, \$button2
                           ]
                          ) ->pack;
    
    MainLoop();