Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Perl/Tk : Trouble with commands and Checkbuttons

by Petras (Friar)
on Sep 16, 2005 at 04:00 UTC ( #492523=perlquestion: print w/ replies, xml ) Need Help??
Petras has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Everybody!

I've finally finished the Llama and have started on the Emu. I'm trying to make a simple Perl/Tk program that displays a grid of Checkbuttons. I want to call a subroutine when the buttons are checked/unchecked (same sub eitherway). Here's the code that works (works but without calling the sub):

#!perl use warnings; use strict; use Tk; my $mw = MainWindow->new; $mw->title("Checkbutton Grid"); my $x_size = 5; my $y_size = 5; my %b_name; for (my $x=0; $x<$x_size; ++$x) { for (my $y=0; $y<$y_size; ++$y) { $mw -> Checkbutton ( -activebackground => "white", ) -> grid ( -row => $x, -column => $y ); } } MainLoop;

But this doesn't do what I expect it to:
$mw -> Checkbutton ( -activebackground => "white", -command => &react ("\"$x\_$y\""); -command => print "hi" # <= this is a change ) -> grid ( -row => $x, -column => $y ); .... sub react { print "$_[0]\n"; }

From the text it seems that when I check/uncheck a Checkbutton that the shell window should print the grid coordinates. Instead, when the script is run the 25 sets of coordinates go straight to the window and nothing happens when the Checkbuttons are checked/unchecked. What am I missing?

For a free bonus, if more-experienced-posters-than-I want to clue me in on the appropriate use of READMORE I'd be willing to learn! cog already instructed me on signatures ;)


UPDATE:pg has the code for what I was looking to do. The other blessed and beautiful monks who replied were all right, their answers match what the Emu says. I was wanting to be able to call a sub through -command and discovered how last night reading the source code for some of the examples in widget.exe. This (thanks, pg and widget.exe authors) is what does what I wanted to do:
-command => [\&display, $x, $y]

So, thanks everyone, for your part in my learning experience.

Cheers!
-P

Don't worry about people stealing your ideas. If your ideas are any good, you'll have to ram them down people's throats.
-Howard Aiken

Comment on Perl/Tk : Trouble with commands and Checkbuttons
Select or Download Code
Re: Perl/Tk : Trouble with commands and Checkbuttons
by spiritway (Vicar) on Sep 16, 2005 at 05:34 UTC

    Your code as posted doesn't compile. You've got a couple of typos in it...

    Try this:

    #! /usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new; $mw->title("Checkbutton Grid"); my $x_size = 5; my $y_size = 5; my %b_name; for (my $x=0; $x<$x_size; ++$x) { for (my $y=0; $y<$y_size; ++$y) { $mw -> Checkbutton ( -activebackground => "white", -command => sub { print "$x,$y\n"; print "hi"; } ) -> grid ( -row => $x, -column => $y ); } } MainLoop;

    Note that when you want to call a subroutine in a -command line, you need to use the sub { ... } language. Note also that the values for $x and $y will be $x_size and $y_size respectively, because by the time you click on a check button, they've been incremented to those values - where they remain.

    What you need to do is to associate a value (x, y) with each of the check buttons, and then use the value in your print statement.

      This will not work, and will print 5,5 regardless which checkbutton you click. The issue is that you used the latest value of $x and $y, not the value at the time when the checkbutton is defined.

        So a minor change to allow the closure to close on the current value would be to create new variables:

        #! /usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new; $mw->title("Checkbutton Grid"); my $x_size = 5; my $y_size = 5; my %b_name; for (my $x=0; $x<$x_size; ++$x) { for (my $y=0; $y<$y_size; ++$y) { my $x_cord = $x; my $y_cord = $y; $mw -> Checkbutton ( -activebackground => "white", -command => sub { print "$x_cord,$y_cord\n +"; print "hi"; } ) -> grid ( -row => $x, -column => $y ); } } MainLoop;
        I'm not saying this is more efficient or better than your other example below (probably is neither), just that it's closer to the OP tried to do while still working.

Re: Perl/Tk : Trouble with commands and Checkbuttons
by pg (Canon) on Sep 16, 2005 at 06:03 UTC
    use warnings; use strict; use Tk; my $mw = MainWindow->new; $mw->title("Checkbutton Grid"); my $x_size = 5; my $y_size = 5; my %b_name; for (my $x=0; $x<$x_size; ++$x) { for (my $y=0; $y<$y_size; ++$y) { $mw -> Checkbutton ( -activebackground => "white", -command => [\&display, $x, $y] ) -> grid ( -row => $x, -column => $y ); } } MainLoop; sub display { my ($x, $y) = @_; print "($x, $y)\n"; }
Re: Perl/Tk : Trouble with commands and Checkbuttons
by Sandy (Deacon) on Sep 16, 2005 at 15:28 UTC
    Just as a side note:

    The -command requires a reference to a subroutine, not code.

    So... your code snippet

    $mw -> Checkbutton ( -activebackground => "white", -command => &react ("\"$x\_$y\""); -command => print "hi" # <= this is a change ) -> grid ( -row => $x, -column => $y ); ....
    should have the -command replaced with
    -command => sub {print "hi"} # <= this is a change ....

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://492523]
Approved by gargle
Front-paged by gargle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (7)
As of 2014-07-13 22:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (252 votes), past polls