要回答有关是否可以将单个绑定应用于多个小部件的具体问题,答案是肯定的。它可能会导致更多的代码行而不是更少,但它很容易做到。
所有 tkinter 小部件都有称为“bindtags”的东西。绑定标签是绑定所附加的“标签”列表。你一直在使用它而不自知。当您绑定到小部件时,绑定实际上不在小部件本身上,而是在与小部件的低级别名称同名的标签上。默认绑定位于与小部件类(底层类,不一定是 python 类)同名的标签上。当你打电话时bind_all
,您正在绑定到标签"all"
.
Bindtags 的伟大之处在于您可以添加和删除您想要的所有标签。因此,您可以添加自己的标签,然后将绑定分配给它bind_class
(我不知道为什么 Tkinter 作者选择这个名字......)。
要记住的重要一点是,绑定标签有一个顺序,并且事件按此顺序处理。如果事件处理程序返回字符串"break"
,在检查任何剩余的绑定标签的绑定之前,事件处理停止。
这样做的实际结果是,如果您希望其他绑定能够覆盖这些新绑定,请将您的绑定标签添加到末尾。如果您希望您的绑定不可能被其他绑定覆盖,请将其放在开头。
Example
import Tkinter as tk
class Example(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
# add bindings to a new tag that we're going to be using
self.bind_class("mytag", "<Enter>", self.on_enter)
self.bind_class("mytag", "<Leave>", self.on_leave)
# create some widgets and give them this tag
for i in range(5):
l = tk.Label(self, text="Button #%s" % i, background="white")
l.pack(side="top")
new_tags = l.bindtags() + ("mytag",)
l.bindtags(new_tags)
def on_enter(self, event):
event.widget.configure(background="bisque")
def on_leave(self, event):
event.widget.configure(background="white")
if __name__ == "__main__":
root = tk.Tk()
view = Example()
view.pack(side="top", fill="both", expand=True)
root.mainloop()
有关绑定标签的更多信息可以在此答案中找到:https://stackoverflow.com/a/11542200/7432 https://stackoverflow.com/a/11542200/7432
另外,bindtags
方法本身记录在 effbot 上基本的小部件方法 http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.bindtags-method页面等其他地方。