7

複数のウィジェットを 1 つの「バインド」でバインドする方法を考えています。

例:

3 つのボタンがあり、ホバリング後に色を変更したいと考えています。

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()

そして、私の目標は、上記の 6 つではなく、2 つのバインド (「入る」イベントと「離れる」イベント用) だけにすることです。

アイデアをありがとう

4

2 に答える 2

9

単一のバインディングを複数のウィジェットに適用できるかどうかという特定の質問に答えるには、答えはイエスです。おそらくコードの行数は少なくなるどころか、より多くなるでしょうが、それは簡単です。

すべての tkinter ウィジェットには、「bindtags」と呼ばれるものがあります。Bindtags は、バインディングが添付される「タグ」のリストです。あなたはそれを知らずにいつもこれを使っています。ウィジェットにバインドする場合、バインディングは実際にはウィジェット自体ではなく、ウィジェットの下位レベルの名前と同じ名前を持つタグにあります。デフォルトのバインディングは、ウィジェット クラスと同じ名前のタグにあります (基になるクラスであり、必ずしも python クラスである必要はありません)。を呼び出すとbind_all、タグにバインドされます"all"

bindtags の優れた点は、タグを自由に追加および削除できることです。したがって、独自のタグを追加してから、それにバインディングを割り当てることができますbind_class(Tkinter の作成者がその名前を選んだ理由はわかりません...)。

覚えておくべき重要なことは、bindtag には順序があり、イベントはこの順序で処理されるということです。イベント ハンドラーが string を返す場合、"break"残りの bindtags のバインドがチェックされる前に、イベント処理が停止します。

これの実際的な結論は、他のバインディングがこれらの新しいバインディングをオーバーライドできるようにしたい場合は、bindtag を末尾に追加することです。バインディングが他のバインディングによってオーバーライドされないようにしたい場合は、それを先頭に置きます。

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()

bindtags に関するもう少し詳しい情報は、この回答にあります: https://stackoverflow.com/a/11542200/7432

また、bindtagsメソッド自体は effbot Basic Widget Methodsページなどで文書化されています。

于 2013-03-12T13:55:18.877 に答える
6
for b in [B1, B2, B3]:
    b.bind("<Enter>", SetColor)
    b.bind("<Leave>", ReturnColor)

さらに進んで、すべてのスニペットを抽象化できます。

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)

ボタンを簡単に追加できるようになりました (入力リストに別のエントリを追加するだけです)。forループの本体を変更することで、すべてのボタンに対して行うことを簡単に変更することもできます。

于 2013-03-12T13:05:26.103 に答える