Perl Tk 绑定到画布项
在我的应用程序中,如果单击一次,则会在画布上绘制圆圈。如果双击,最近添加的点将连接到多边形。
我需要将新的圆位置调整到单击(和现有)点的中心。也就是说,如果我单击现有点内部,那么新点将与该现有点匹配。
我尝试为点击圆圈和整个画布设置单独的回调,但他们一一调用。双击后也会调用单击圆圈的回调...
有没有办法停止事件传播?
use strict;
use Tk;
my $countries = [];
push(@$countries, []);
my $mw = MainWindow->new;
$mw->title("Graph colorer");
$mw->minsize(600, 600);
$mw->resizable(0, 0);
my $canvas = $mw->Canvas(-background => 'white')->pack(-expand => 1,
-fill => 'both');
$canvas->bind('point', "<Button-1>", [ \&smart_point, Ev('x'), Ev('y') ]);
$canvas->Tk::bind("<Button-1>", [ \&append_point, Ev('x'), Ev('y') ]);
$canvas->Tk::bind("<Double-Button-1>", [ \&draw_last_country ]);
sub append_point {
my ($canv, $x, $y) = @_;
my $last_country = $countries->[-1];
my ($canvx, $canvy) = ($canv->canvasx($x), $canv->canvasy($y));
push(@$last_country, $canvx, $canvy);
$canv->createOval($canvx-5, $canvy-5, $canvx+5, $canvy+5, -tags => 'point',
-fill => 'green');
print "pushed (x,y) = ", $canvx, ", ", $canvy, "\n";
}
sub draw_last_country {
my $canv = shift;
$canv->createPolygon($countries->[-1]);
push(@$countries, []);
}
sub smart_point {
my $canv = shift;
my $id = $canv->find('withtag', 'current');
my ($x1, $y1, $x2, $y2) = $canv->coords($id);
print "clicked (x,y) = ", ($x2-$x1)/2, ", ", ($y2-$y1)/2, "\n";
}
MainLoop;
In my application if click once then circle will be drawed on canvas. If double click then recently added points will be connected to polygon.
I need to adjust new circle position to the center of clicked (and existing) point. That is if I click inside existing point then new point will match this existing point.
I tried to set separate callbacks for click on circle and on whole canvas but they called one-by-one. And callback for click on circle is also called after double-click...
Is there a way to stop event propagation?
use strict;
use Tk;
my $countries = [];
push(@$countries, []);
my $mw = MainWindow->new;
$mw->title("Graph colorer");
$mw->minsize(600, 600);
$mw->resizable(0, 0);
my $canvas = $mw->Canvas(-background => 'white')->pack(-expand => 1,
-fill => 'both');
$canvas->bind('point', "<Button-1>", [ \&smart_point, Ev('x'), Ev('y') ]);
$canvas->Tk::bind("<Button-1>", [ \&append_point, Ev('x'), Ev('y') ]);
$canvas->Tk::bind("<Double-Button-1>", [ \&draw_last_country ]);
sub append_point {
my ($canv, $x, $y) = @_;
my $last_country = $countries->[-1];
my ($canvx, $canvy) = ($canv->canvasx($x), $canv->canvasy($y));
push(@$last_country, $canvx, $canvy);
$canv->createOval($canvx-5, $canvy-5, $canvx+5, $canvy+5, -tags => 'point',
-fill => 'green');
print "pushed (x,y) = ", $canvx, ", ", $canvy, "\n";
}
sub draw_last_country {
my $canv = shift;
$canv->createPolygon($countries->[-1]);
push(@$countries, []);
}
sub smart_point {
my $canv = shift;
my $id = $canv->find('withtag', 'current');
my ($x1, $y1, $x2, $y2) = $canv->coords($id);
print "clicked (x,y) = ", ($x2-$x1)/2, ", ", ($y2-$y1)/2, "\n";
}
MainLoop;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
画布项目的事件处理与窗口事件的处理完全分开(好吧,有一个链接,但它不在您可以操作的级别)。您必须自己进行互锁,例如,通过在绑定之间共享一个变量。
The processing of events for canvas items is completely separate from the processing of events for windows (OK, there's a link, but it's not at a level that you can manipulate). You have to do the interlock yourself, e.g., by having a variable that's shared between the bindings.
好的,我刚刚删除了椭圆形单击回调,并检查是否在画布单击回调中的现有椭圆形内部或外部单击。
Ok, I've just remove oval-click-callback and check if clicked inside or outside of an existing oval in canvas-click-callback.