tkinter:应用程序终止后事件绑定仍然存在吗?

tkinter: event binding remains after application terminates?

我是 运行宁 Python 3.4 中的 tkinter。即使在应用程序终止后,按钮事件似乎仍与命令绑定。代码片段:

# application class
class DataSel:
    def __init__(self,parent):
        self.parent = parent
        <...>
        self.button_sel = tk.Button(self.parent,text='Select')
        self.button_sel.grid(row=1,sticky='nesw')
        self.button_sel.bind('<Button-1>',self.sel_click)

        self.button_quit = tk.Button(self.parent,text='Quit')
        self.button_quit.grid(row=2,sticky='nesw')
        self.button_quit.bind('<Button-1>',self.quit_click)

    def sel_click(self,event):
        self.filename = askopenfilename(parent=self.parent)
        <...>

    def quit_click(self,event):
        self.parent.destroy()

# main part of application
root = tk.Tk()
root.lift()
sel = DataSel(root)
root.lift()
root.mainloop()

当我从头开始重新启动解释器和运行这个应用程序时,没有错误消息。但是,在 sel_click 方法完成后,button_sel 按钮仍处于按下状态(浅浮雕)。然后,如果我退出应用程序并重新 运行 它,我会在 shell:

中收到以下消息
invalid command name ".94227256"
    while executing
"$w cget -state"
    (procedure "tk::ButtonDown" line 12)
    invoked from within
"tk::ButtonDown .94227256"
    (command bound to event)

其中数字 .94227256 每次我重新 运行 时都会改变。

除了此消息和按钮保持低浮雕状态之外,所有其他功能都正常。但似乎按钮事件以某种方式绑定到陈旧的命令!

实际情况是您的绑定发生在按钮小部件能够处理同一事件之前。您在 期间 处理事件并且您没有告诉 Tkinter 停止进一步处理事件。因此,当 Tkinter 开始让小部件处理点击事件时,window 不再存在并且 tkinter 会抛出错误。

问题的根源在于您将绑定放在按钮上。你不应该那样做。如果要从按钮调用函数,则需要使用按钮的 command 属性。

如果你真的认为你需要通过绑定(而不是通过 command 属性)来做到这一点,你需要你的函数 return '"break"` 来告诉 tkinter停止对该事件的任何进一步处理。