The man pages about bindings, "Tk::bind", has the following to say:
If callback contains any Ev(%) calls, then
each "nested" Ev(%) "callback" will be evaluated when the
event occurs to form arguments to be passed to the main
callback. The replacement depends on the character %, as
defined in the list below. Unless otherwise indicated, the
replacement string is the numeric (decimal) value of the
given field from the current event.
This is from the section "BINDING CALLBACKS AND SUBSTITUTIONS".
This leads me to believe that the following should work:
#!/usr/local/bin/perl -w
use strict;
use Tk;
sub click {print "@_\n"}
my $mw = MainWindow -> new -> toplevel;
my $canvas = $mw -> Canvas (width => 100,
height => 100) -> pack;
$canvas -> create (rectangle => 1, 1, 101, 101,
fill => 'red',
tags => [qw /test/],
outline => undef);
$canvas -> bind ('test', "<1>" => sub {click (Ev ('x'), Ev ('y'))});
MainLoop;
__END__
Of course, it doesn't. (Which, after working half a week with Perl/Tk
is no longer a surprise to me).
It doesn't print the coordinates. It prints lines like:
Tk::Ev=SCALAR(0xba528) Tk::Ev=SCALAR(0x2af248)
Isn't that helpful? :(
I can get the coordinates with:
#!/usr/local/bin/perl -w
use strict;
use Tk;
sub click {my $canvas = shift;
my $e = $canvas -> XEvent;
my @c = ($e -> x, $e -> y);
print "@c\n"}
my $mw = MainWindow -> new -> toplevel;
my $canvas = $mw -> Canvas (width => 100,
height => 100) -> pack;
$canvas -> create (rectangle => 1, 1, 101, 101,
fill => 'red',
tags => [qw /test/],
outline => undef);
$canvas -> bind ('test', "<1>" => sub {click ($canvas)});
MainLoop;
__END__
But the only man pages that mentions XEvent is the one about Tcl vs Perl.
What *is* the appropriate way to get the coordinates?
Abigail
--
sub _'_{$_'_=~s/$a/$_/}map{$$_=$Z++}Y,a..z,A..X;*{($_::_=sprintf+q=%X==>"$A$Y".
"$b$r$T$u")=~s~0~O~g;map+_::_,U=>T=>L=>$Z;$_::_}=*_;sub _{print+/.*::(.*)/s}
*_'_=*{chr($b*$e)};*__=*{chr(1<<$e)};
_::_(r(e(k(c(a(H(__(l(r(e(P(__(r(e(h(t(o(n(a(__(t(us(J())))))))))))))))))))))))
Ahem,Perl/Tk documentation is a problem isn't it? In manpage or html
document for Tk::callbacks there some examples given. The format of the
examples seems to work e.g.
#!/usr/bin/perl -w
use strict;
use Tk;
sub click {print "@_\n"}
my $mw = MainWindow -> new -> toplevel;
my $canvas = $mw -> Canvas (width => 100,
height => 100) -> pack;
$canvas -> create (rectangle => 1, 1, 101, 101,
fill => 'red',
tags => [qw /test/],
outline => undef);
$canvas -> bind ('test', "<1>" => ['main::click', Ev ('x'), Ev ('y')]);
MainLoop;
__END__
Produces the stuff below. I admit the widget as the first argument is a
little unexpected but now that you know... Oh yeah this is with
Tk402.004
David
Tk::Canvas=HASH(0x81e2dc8) 71 66
Tk::Canvas=HASH(0x81e2dc8) 76 69
Tk::Canvas=HASH(0x81e2dc8) 76 69
> $canvas -> bind ('test', "<1>" => ['main::click', Ev ('x'), Ev ('y')]);
[...]
> Produces the stuff below. I admit the widget as the first argument is a
> little unexpected but now that you know... Oh yeah this is with
> Tk402.004
This is actually described functionality for the bind() method. If
you want to get around it, you can use the sub{} notation for
callbacks:
$canvas->bind('test',"<1>" => sub {main::click(Ev('x'), Ev('y'))});
- ben
--
Ben Cordes bco...@quadri.hlo.dec.com
Hardware Design Engineer, Compaq Computer Corporation
Uhm, that was exactly my problem. That does *not* work:
#!/usr/local/bin/perl -w
use strict;
use Tk;
sub click {print "@_\n"}
my $mw = MainWindow -> new -> toplevel;
my $canvas = $mw -> Canvas (width => 100,
height => 100) -> pack;
$canvas -> create (rectangle => 1, 1, 101, 101,
fill => 'red',
tags => [qw /test/],
outline => undef);
$canvas -> bind ('test', "<1>" => sub {main::click (Ev('x'), Ev('y'))});
MainLoop;
__END__
That prints:
Tk::Ev=SCALAR(0xba528) Tk::Ev=SCALAR(0x2af248)
Abigail
--
perl5.004 -wMMath::BigInt -e'$^V=new Math::BigInt+qq;$^F$^W783$[$%9889$^F47$|88768$^W596577669$%$^W5$^F3364$[$^W$^F$|838747$[8889739$%$|$^F673$%$^W98$^F76777$=56;;$^U=substr($]=>$|=>5)*(q.25..($^W=@^V))=>do{print+chr$^V%$^U;$^V/=$^U}while$^V!=$^W'
> Problem: I have a canvas, I want to catch mouse clicks, and want to
> know the coordinates of where a click happened.
> The man pages about bindings, "Tk::bind", has the following to say:
> If callback contains any Ev(%) calls, then
> each "nested" Ev(%) "callback" will be evaluated when the
> event occurs to form arguments to be passed to the main
> callback. The replacement depends on the character %, as
> defined in the list below. Unless otherwise indicated, the
> replacement string is the numeric (decimal) value of the
> given field from the current event.
> This is from the section "BINDING CALLBACKS AND SUBSTITUTIONS".
> This leads me to believe that the following should work:
> #!/usr/local/bin/perl -w
> use strict;
> use Tk;
> sub click {print "@_\n"}
> my $mw = MainWindow -> new -> toplevel;
> my $canvas = $mw -> Canvas (width => 100,
> height => 100) -> pack;
> $canvas -> create (rectangle => 1, 1, 101, 101,
> fill => 'red',
> tags => [qw /test/],
> outline => undef);
> $canvas -> bind ('test', "<1>" => sub {click (Ev ('x'), Ev ('y'))});
> MainLoop;
> __END__
> Of course, it doesn't. (Which, after working half a week with Perl/Tk
> is no longer a surprise to me).
> It doesn't print the coordinates. It prints lines like:
> Tk::Ev=SCALAR(0xba528) Tk::Ev=SCALAR(0x2af248)
> Isn't that helpful? :(
Ev() is a Tk thing - in previous example it's inside a sub{} which is a Perl
thing. You want to let Tk do the driving:
$canvas -> bind ('test', "<1>" => [\&click, Ev ('x'), Ev ('y')]);
This "extended" callback format, an array ref, defines element 0 to be a code ref or a
method name, followed by optional arguments. As with all bind() commands, the object
of the bind (here $canvas) is implicitly passed as the first argument. Now results
look like this:
Tk::Canvas=HASH(0x821df6c) 64 62
Tk::Canvas=HASH(0x821df6c) 57 73
Tk::Canvas=HASH(0x821df6c) 54 57
Ev() can be even fancier:
$canvas->bind('test', '<1>', [\&click, Ev(['itemcget', 1, -fill])]);
or
$list->bind('<a>', [\&subr, Ev(['get','active']), 1]);
Here Tk first invokes the inner callback ['get', 'active'] - send a get() message to
the listbox $list with one argument, 'active'. The result of that evaluation is passed
as the *second* argument to &subr - remember that the object ref $list is implicity
passed as the first argument. The digit 1 is argument three.
> I can get the coordinates with:
> #!/usr/local/bin/perl -w
> use strict;
> use Tk;
> sub click {my $canvas = shift;
> my $e = $canvas -> XEvent;
> my @c = ($e -> x, $e -> y);
> print "@c\n"}
> my $mw = MainWindow -> new -> toplevel;
> my $canvas = $mw -> Canvas (width => 100,
> height => 100) -> pack;
> $canvas -> create (rectangle => 1, 1, 101, 101,
> fill => 'red',
> tags => [qw /test/],
> outline => undef);
> $canvas -> bind ('test', "<1>" => sub {click ($canvas)});
> MainLoop;
> __END__
> But the only man pages that mentions XEvent is the one about Tcl vs Perl.
> What *is* the appropriate way to get the coordinates?
Both are appropriate ways....
Oh, a leading dash on options is highly recommended... you'll get burned sooner
rather than later (-: