如何在Tkinter中使用一个"绑定"绑定多个小部件?

Mil*_*ála 5 python bind tkinter widget

我想知道如何用一个"绑定"绑定多个小部件.

例如:

我有三个按钮,我想在悬停后改变颜色.

from Tkinter import *

def SetColor(event):
    event.widget.config(bg="red")
    return

def ReturnColor(event):
    event.widget.config(bg="white")
    return

root = Tk()

B1 = Button(root,text="Button 1", bg="white")
B1.pack()

B2 = Button(root, text="Button2", bg="white")
B2.pack()

B3 = Button(root, text= "Button 3", bg="white")
B3.pack()

B1.bind("<Enter>",SetColor)
B2.bind("<Enter>",SetColor)
B3.bind("<Enter>",SetColor)

B1.bind("<Leave>",ReturnColor)
B2.bind("<Leave>",ReturnColor)
B3.bind("<Leave>",ReturnColor)

root.mainloop()
Run Code Online (Sandbox Code Playgroud)

我的目标是只有两个绑定(用于"Enter"和"Leave"事件)而不是上面的六个.

谢谢你的任何想法

Bry*_*ley 7

要回答关于是否可以将单个绑定应用于多个小部件的具体问题,答案是肯定的.它可能会产生更多的代码而不是更少,但它很容易做到.

所有tkinter小部件都有一个叫做"bindtags"的东西.Bindtags是附加绑定的"标签"列表.你总是在不知情的情况下使用它.绑定到窗口小部件时,绑定实际上不在窗口小部件本身上,而是在与窗口小部件的低级别名称同名的标记上.默认绑定位于与窗口小部件(与基础类,不一定是python类)同名的标记上.当你打电话时bind_all,你就绑定了标签"all".

关于bindtags的好处是你可以随意添加和删除标签.因此,您可以添加自己的标记,然后为其分配绑定bind_class(我不知道为什么Tkinter作者选择了该名称...).

要记住的一件重要事情是bindtags有一个订单,事件按此顺序处理.如果事件处理程序返回字符串"break",则在检查任何剩余的绑定标记之前,事件处理将停止.

这样做的实际结果是,如果您希望其他绑定能够覆盖这些新绑定,请将绑定标签添加到最后.如果您希望绑定无法被其他绑定覆盖,请将其置于开头.

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()
Run Code Online (Sandbox Code Playgroud)

有关bindtags的更多信息可以在这个答案中找到:https://stackoverflow.com/a/11542200/7432

此外,该bindtags方法本身记录在effbot Basic Widget Methods页面中.


Ben*_*son 6

for b in [B1, B2, B3]:
    b.bind("<Enter>", SetColor)
    b.bind("<Leave>", ReturnColor)
Run Code Online (Sandbox Code Playgroud)

您可以进一步抽象所有代码段:

for s in ["button 1", "button 2", "button 3"]:
    b=Button(root, text=s, bg="white")
    b.pack()
    b.bind("<Enter>", SetColor)
    b.bind("<Leave>", ReturnColor)
Run Code Online (Sandbox Code Playgroud)

现在可以轻松添加额外的按钮(只需在输入列表中添加另一个条目).通过更改for循环体,也可以轻松地将所做的操作更改为所有按钮.