我怎样才能停止在Tkinter举办活动?

时间:2013-01-23 02:05:46

标签: python events tkinter

我有一些像这样的代码

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()

当我点击Canvas时,我在画布上有#34;&#34;控制台中的消息。 当我点击椭圆形时,我有两条消息&#34;在椭圆形&#34;和&#34;在画布&#34;,但我想只有第一条消息。有没有办法阻止事件的发生?

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

2 个答案:

答案 0 :(得分: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下,没有其他更简单的方法可以解决此问题。

答案 1 :(得分:0)

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

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

  1. 围绕所希望的callback创建一个包装器,即一个可调用的类实例
  2. 调用类实例时,运行"break"并检查其结果。
    • 如果结果为bind,则暂时劫持事件传播:Canvas tag_bind窗口小部件到绑定到unbind的同一事件,并返回空回调。然后,在空闲时间"break"
    • 之后
    • 如果结果不是Canvas:什么也不做,事件将自动传播到Text
  3. 上面的链接列出了{{1}}窗口小部件的完整工作示例,但它可以立即转移到Canvas窗口小部件。