zentara wrote:

> The first is that you cannot count on a sub call always passing
> the caller. In some languages, like gtk2, when you call a sub,
> $_[0]  is always the widget that called it.  But in Tk, sometimes it is,
> and sometimes it isn't.  If in doubt, just print @_ in your subs and
> see what is coming in.
> Tk dosn't pass it's widget reference in callbacks.
> Only the bind() method will implicity pass a widget reference, and even
> this default (and generally preferred) action can be defeated.
> I think the canvas widget is good about this.
>
> Look at this program to see how it works.
> ######################################################
> #!/usr/bin/perl
> use strict;
> use Tk;
> #use Data::Dumper;
>
> my $mw = MainWindow->new;
>
> for(0..4){
> my $b = $mw->Button(-text => "Hello World$_",
>                          -command=>[\&change])->pack;
> }
> MainLoop;
>
> sub change {
> #Tk dosn't pass it's widget reference in callbacks
> #Only the bind() method will implicity pass a widget reference, and even
> #this default (and generally preferred) action can be defeated.
> print "sub_input->@_\n"; #prints nothing
> my $caller=$Tk::widget;
> print "$caller\n";
> $caller->configure(-text=>"Hello Stranger");
> #print Dumper([$caller]);
>
> }
> ####################################################
>
> The second thing to watch out for is the -command=>
> syntax. The -command expects a sub or codefref which
> can be performed LATER.
> -command=>[\&change])  works
> but occaisionally you will run into situations
> where you need the sub{ } syntax.
> For instance try the above command as:
> -command=>[Tk::exit])->pack;
> and the command will execute as soon as the button
> is created, so the program will prematurely terminate.
> And it's a hard bug to find.
>
> But it will work as
> -command=>sub{[Tk::exit]})->pack;
> which will exit on the first button click.

Tk can be very tricky with its callbacks.  Some widgets already have machineries
set up for handling thier command parameter.  For instance, the Tree widget [my
personal favorite] has a browsecmd option that passes the path of the node by
default.  Sometimes you just have to feel around within any context.
Unfortunately, the docs don't always shed much light.  They show many ways to
handle events, but still you have to pin down what is applicable per context.

One general approach that has usually worked well with me is, as in my sample, to
offer an anonymous array.  Most Tk event handlers will recognize it correctly,
take the first element as the code reference, and further elements as the
argument list.  I think there may be cases where it will shift a default argument
in front of those offered, but don't take me word on this--test!

-command => [\&my_function, $my_arg1, $my_arg2]

Joseph


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to