2013-03-12 21 views
5

Zastanawiam się, jak powiązać wiele widżetów z jednym "bind".Jak powiązać wiele widżetów z jednym "bind" w Tkinter?

Dla expample:

Mam trzy przyciski i chcę zmienić ich kolor po uciążliwy.

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

Moim celem jest posiadanie tylko dwóch wiązań (dla zdarzeń "Wejdź" i "Opuść") zamiast sześciu jak wyżej.

Dziękuję za wszelkie pomysły

Odpowiedz

5

robi to samo dla wielu obiektów? Brzmi jak pętla for.

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

Można pójść dalej i streszczenie wszystkich fragmencie:

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) 

Teraz łatwo jest dodać dodatkowe przyciski (wystarczy dodać kolejny wpis do listy wejściowego). Łatwo też zmienić to, co robisz na wszystkich przyciskach, zmieniając korpus pętli for.

+0

Możesz również ustawić parametry za pomocą zagnieżdżonego słownika: 'bParams = {'button1': {'bg': 'red', 'command' = self.frame.quit, ...}, ... } '.Nie jestem pewien, czy można dodać polecenia w słowniku, ale w przeciwnym razie można to zrobić: 'b = Button (root, text = s, bg = bParams [b], ...)'. –

+0

Och, dziękuję. To może zadziałać :) –

6

Aby odpowiedzieć na pytanie, czy można zastosować pojedyncze wiązanie dla wielu widżetów, odpowiedź brzmi "tak". Prawdopodobnie spowoduje więcej linii kodu, a nie mniej, ale jest to łatwe.

Wszystkie widżety tkinter mają coś, co nazywa się "bindtags". Bindtagi to lista "tagów", do których dołączone są wiązania. Korzystasz z tego cały czas, nie wiedząc o tym. Po powiązaniu z widgetem powiązanie nie znajduje się w rzeczywistości w widgecie jako takim, ale w znaczniku o tej samej nazwie, co nazwa niskiego poziomu widgetu. Domyślne powiązania dotyczą znacznika o tej samej nazwie co klasa widgetu (podstawowa klasa, niekoniecznie klasa python). A kiedy zadzwonisz pod numer bind_all, jesteś powiązany z tagiem "all".

Wspaniałą cechą bindtags jest możliwość dodawania i usuwania tagów, które tylko chcesz. Możesz więc dodać własny tag, a następnie przypisać do niego powiązanie za pomocą bind_class (nie wiem, dlaczego autorzy Tkintera wybrali to imię ...).

Należy pamiętać, że bindtags mają zamówienie, a zdarzenia są obsługiwane w tej kolejności. Jeśli procedura obsługi zdarzeń zwróci ciąg znaków "break", obsługa zdarzeń zatrzyma się przed sprawdzeniem wszystkich bindtagów pod kątem powiązań.

Praktycznym rezultatem tego jest, jeśli chcesz, aby inne wiązania były w stanie zastąpić te nowe wiązania, dodaj swój bindtag do końca. Jeśli chcesz, aby wiązania nie mogły zostać zastąpione innymi wiązaniami, umieść je na początku.

Przykład

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

Trochę więcej informacji na temat bindtags można znaleźć w tej odpowiedzi: https://stackoverflow.com/a/11542200/7432

Również metoda bindtags sama jest udokumentowana na stronie effbot Basic Widget Methods wśród innych miejscach.

Powiązane problemy