【问题标题】:Destroy events executes the binded function 5 times销毁事件执行绑定函数 5 次
【发布时间】:2019-10-10 18:02:18
【问题描述】:

我在 python 中有一些使用 tkinter 模块的代码。我一直在尝试将函数绑定到"<Destroy>",但每次运行代码并关闭窗口时,绑定的函数都会执行 5 次。代码如下:

def bind_events(self):
        ''' binding the events to their functions '''

        self.master.bind("<Destroy>", lambda x: print("OK"))

这段代码是一个类函数。然后我得到这个输出:

>>> OK
OK
OK
OK
OK

有没有办法解决这个问题。谢谢你的时间,对不起我的英语。

【问题讨论】:

    标签: python events tkinter bind destroy


    【解决方案1】:

    如果您将事件绑定到根窗口,则该绑定将附加到每个小部件。因此,如果您有一个带有四个其他小部件的根窗口,当您销毁该窗口时,您的绑定函数将被调用五次 - 每个小部件一次。

    看到这种情况发生的一种简单方法是修改您的函数,使其不仅打印“OK”,还打印与事件关联的小部件:

    self.master.bind("<Destroy>", lambda event: print("{}: OK".format(event.widget)))
    

    这与您实际上并没有绑定到小部件本身的事实有关,您正在绑定到同名的绑定标签小部件。除了自身之外,每个小部件都有一组与之关联的绑定标签:

    • 它自己会有一个绑定标签
    • 它将有一个小部件类的绑定标签(这是小部件获得其默认行为的方式)
    • 它将为该小部件的顶层窗口(或根)提供一个绑定标签,
    • 它将具有特殊的绑定标签“all”

    因此,当您绑定到根窗口时,任何小部件都会继承该绑定。如果你想绑定到根窗口并且只绑定根窗口,最常见的解决方案是绑定到一个函数,并且在那个函数中只采取一个动作的widget就是根窗口。

    例如:

    def on_destroy(self, event):
        if event.widget == self.master:
            print("{}: OK".format(event.widget))
    
    self.master.bind("<Destroy>", self.on_destroy)
    

    【讨论】:

    • 哼。这太有趣了。绑定到根本原因时我从未发现问题,所以我从没想过在绑定时打印。我想当你想到它时认为它是有道理的。如果我在任何时候绑定到一个框架,那么我在该框架中执行某项操作就会触发绑定。以为我认为这只是因为我在框架内。那么真正的原因是因为该框架内的所有内容都继承了绑定吗?
    • @Mike-SMT:“如果我在任何时候绑定到某个框架,我在该框架中执行某项操作就会触发绑定。” 我不确定你那是什么意思。这仅在绑定到根窗口或顶层窗口时才会出现问题。框架内的小部件不会响应绑定到框架本身的事件。
    • 所以我最初的假设是如何绑定到框架是正确的,并且这种行为只与根绑定或顶层绑定有关?因此,为了澄清我的意思是我在绑定到任何容器时最初的假设是,如果我的焦点位于该容器内的任何位置,那么绑定将由我设置的任何条件触发。但是您是说root和top并非如此。它将绑定设置为所有子小部件。除非我误会了。
    • @Mike-SMT:小部件具有绑定标签,它是确定小部件响应哪些事件的标签。绑定标签包括顶层或根窗口的标签。它们确实包含任何其他容器的标签。
    • 非常感谢您抽出宝贵时间,非常感谢。我在尝试创建一个简单的 tkinter 文本编辑器时发现了这个问题,为了询问用户是否要保存文件,我必须将销毁事件绑定到将打开问题对话框的特定销毁函数。
    猜你喜欢
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    相关资源
    最近更新 更多