5

我有一些这样的代码

from Tkinter import *
master = Tk()
def oval_mouse_click(event):
    print "in oval"
def canvas_mouse_click(event):
    print "in canvas"
w = Canvas(master, width = 800, height = 600)
uid = w.create_oval(390, 290, 410, 310, fill='blue')
w.tag_bind(uid, "<Button-1>", lambda x: oval_mouse_click(x))
w.bind("<Button-1>" , canvas_mouse_click)
w.pack()
mainloop()

当我单击画布时,控制台中有“画布中”消息。当我单击椭圆形时,我有两条消息“椭圆形”和“画布中”,但我只想收到第一条消息。有什么方法可以阻止事件引发?

我可以用一些全局标志来完成这项任务,但我认为 Tkl 应该有更自然的方式。

4

2 回答 2

2

这是处理您的问题的最简单示例:

import Tkinter

def oval_mouse_click(event):
    print "in oval"
    event.widget.tag_click = True

def canvas_mouse_click(event):
    if event.widget.tag_click:
        event.widget.tag_click = False
        return
    print "in canvas"

root = Tkinter.Tk()
canvas = Tkinter.Canvas(width=400, height=300)
oid = canvas.create_oval(400/2-10, 300/2-10, 400/2+10, 300/2+10, fill='blue')
canvas.tag_click = False
canvas.tag_bind(oid, "<Button-1>", oval_mouse_click)
canvas.bind("<Button-1>" , canvas_mouse_click)
canvas.pack()
root.mainloop()

没有其他更简单的方法可以在Canvas.

于 2013-01-23T12:58:23.587 回答
1

我刚刚在Python tkinter:stop event propagation in text widgets tags 中发布了针对类似问题的改进解决方案。

核心思想与之前的解决方案相同:Canvas通过将小部件绑定到与tag_bind. 我提出的改进解决方案现在可以模拟return "break"Tk 的其他绑定+回调对的预期行为。简而言之:

  1. 围绕希望创建一个包装器callback,即一个可调用的类实例
  2. 当调用类实例时,运行callback并检查其结果。
    • 如果结果是"break",则暂时劫持事件传播:bindCanvas部件与绑定到 的相同事件tag_bind,回调为空。然后,在一段空闲时间之后,unbind.
    • 如果结果不是"break":什么都不做,事件将Canvas自动传播到

上面的链接列出了一个完整的Text小部件工作示例,但它可以立即转移到 Canvas 小部件。

于 2013-04-16T14:03:32.373 回答