虚拟事件多重绑定无法按预期工作

时间:2015-08-04 13:28:54

标签: events tkinter

以下是我的代码的简化版本:

from tkinter import *
class MyCustomWidget(Canvas):

    def __init__(self, parent = None, **options):
        Canvas.__init__(self, parent, options)
        self.box = self.create_rectangle(0, 0, 300, 300,fill="blue")
        self.bind('<Button-1>', self.on_clicked)
        self.tag_bind(self.box, '<B1-Motion>', self.on_clicked)  

    def on_clicked(self, event):
        print( "inner method called")

#now outside this class:
def my_callback(event=None):
    print ("outer method called")

root = Tk()
my_widget = MyCustomWidget()
my_widget.event_add('<<my_event>>', '<B1-Motion>', '<Button-1>')
my_widget.bind('<<my_event>>', my_callback)
my_widget.pack()
root.mainloop()

当我运行此代码并将鼠标(B1-Motion)移到蓝框上时,它会调用内部和外部方法,因此我得到以下输出:

inner method called
outer method called

但是,当我单击蓝色框(Button-1)时,它只调用内部方法,输出为:

inner method called

我期待在任何一种情况下调用这两种方法。关于为什么这应该这样做的任何解释?

1 个答案:

答案 0 :(得分:2)

Tkinter不会为同一事件调用两个回调。来自官方tk文档:

  

如果多个绑定与特定事件匹配且它们具有相同的标记,则选择最具体的绑定并评估其脚本。按顺序应用以下测试,以确定几个匹配序列中的哪一个更具体:

     

a)指定特定按钮或键的事件模式比不具有该特定按钮或键的事件更具体;

     

(b)较长的序列(就匹配的事件数而言)比较短的序列更具特异性;

     

(c)如果一个模式中指定的修饰符是另一个模式中修饰符的子集,则具有更多修饰符的模式更具体。

     

(d)物理模式与序列匹配的虚拟事件的特定性低于与虚拟事件无关的相同物理模式。

     

(e)给定一个匹配两个或多个虚拟事件的序列,将选择其中一个虚拟事件,但订单未定义。

当您单击鼠标按钮时,您有多个匹配的绑定 - <<my_event>>上的绑定和<1>上的绑定。 <1>的绑定比<<my_event>>上的绑定更具体,因此是选择的绑定。