in reply to Re: reset checkbutton value
in thread reset checkbutton value

Thank you AppleFritter.
Where exactly did I go wrong? Could you explain please? I had a look at the doc and seen that deselect would deselect the checkbuttons but I tried and no luck. I guess I was selecting the wrong element to reference.



I see what made the difference was the button sub.

my $connButton = $mw->Button( -text => "Connect", -command => sub { my @networks = grep { defined } @checkbox; if(@networks == 1) { say $networks[0]; } else { say "Select one network, please."; } }

I didn't post with the original code, at least I dont think but here was my version of the checkbutton function. Essentially the same as yours.



open my $FILE, '<', "ESSID", or die "Can't open file: $!"; my @lines = <$FILE>; my @Sel; my $i = 0; my @Selected; my $checkButton; foreach my $n ( @lines ) { chomp $n; $checkButton = $mw->Checkbutton( -text => "$n", -onvalue => 1, -offvalue => 0, -command => sub{push +(@Sel, $n)} && sub{ $Selected[$i] = defined $Selected[$i] ? undef : $ +n;}, -variable => \$Selec +ted[$i], )->pack( -side => 'top', + -anchor => 'nw' ); $i=$i+1; }

Replies are listed 'Best First'.
Re^3: reset checkbutton value
by AppleFritter (Vicar) on Sep 09, 2014 at 23:19 UTC

    Where you mostly went wrong, I think, was in only pushing to @Sel and not popping from it. In other words, if you clicked on a checkbox, you'd push its value to @Sel; and if you clicked it again to deselect it, you'd just push again. The list would grow longer and longer, and things would not work as intended.

    Meanwhile, this:

    -command => sub{push(@Sel, $n)} && sub{ $Selected[$i] = defined $Selec +ted[$i] ? undef : $n;}

    most likely will not do what you may think; although you can use the && operator on anonymous subroutine references (they're scalars, after all), they'll always be a true value, and the operator will return the last value evaluated, in this case the second reference (see C style Logical And in perlop). So the above line is really equivalent to

    -command => sub{ $Selected[$i] = defined $Selected[$i] ? undef : $n;}

    Now, this IS fairly close to what I wrote, of course, but:

    • You're not pushing to @Sel at all anymore, so the check if it's got one element on it will always fail.
    • Your anonymous subroutines use the $i you declared outside the loop - and $i is 5 when the loop is done, so all your checkboxes will operate on $Selected[5].

    I got around the latter by introducing a new variable inside the loop that holds the current value of $i; this goes out out of scope at the end of the loop body, so in the next loop iteration, a new variable with the same name is created, and each anonymous subroutine sees a different variable, one that keeps the right value of $i. (It's worth noting that even though the variables go out of scope, their duration does not end, as they're still visible to the anonymous subroutines.)

    This is perhaps a little difficult to wrap your head around at first. For more information on scope and duration, I'd recommend Mark Dominus's Higher Order Perl (available as a free PDF here, or a dead-tree edition here), pp. 71-76.