9.4. Using Bind with a Canvas

When you try to use the bindmethod with a canvas widget, you'll run into some unexpected problems. You'll either get an error and your script won't run, or your script will run but your bind won't seem to have any effect. In order to get around this, you'll need to use the explicit Tk::bind instead of just bind (because the canvas has its own bindmethod that you have to avoid using):

$canvas = $mw->Canvas();
$canvas->Tk::bind("<Button-1>", sub { print "bind!\n"; });

You can also use SUPER::bind instead ofTk::bind. Either way will work.[1]

[1] For those using Tk8.0: You can use canvasBind instead of Tk::bind. I'll refer to Tk::bind throughout the rest of the chapter, but note that you should use canvasBind instead.

If you used the Scrolledmethod to create your canvas, you'll have an added difficulty; you'll have to use the Subwidgetmethod to get to the canvas widget:

$canvas = $mw->Scrolled("Canvas");
$real_canvas = $canvas->Subwidget("canvas");
$real_canvas->Tk::bind("<Button-1>", sub { print "bind!\n" });

Other than this one small annoyance, bind works just as you would expect it would. Here's a quick (and fairly useful) example that will print out the coordinate you clicked on:

$c = $mw->Scrolled("Canvas")->pack();
$canvas = $c->Subwidget("canvas");
$canvas->Tk::bind("<Button-1>", [ \&print_xy, Ev('x'), Ev('y') ]);
sub print_xy {
  my ($canv, $x, $y) = @_;
  print "(x,y) = ", $canv->canvasx($x), ", ", $canv->canvasy($y), "\n";
}

This example prints ...

Get Learning Perl/Tk now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.