2013-03-12 57 views
5

Tôi tự hỏi làm thế nào để ràng buộc nhiều vật dụng với một "ràng buộc".Làm cách nào để liên kết nhiều tiện ích với một "liên kết" trong Tkinter?

Ví dụ:

Tôi có ba nút và tôi muốn thay đổi màu sắc sau khi di chuột.

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

Và mục tiêu của tôi là chỉ có hai liên kết (cho các sự kiện "Enter" và "Leave") thay vì sáu như trên.

Cảm ơn bạn về bất kỳ ý tưởng nào

Trả lời

5

Làm tương tự với nhiều đối tượng? Âm thanh như một vòng lặp for với tôi.

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

Bạn có thể đi xa hơn và trừu tượng tất cả các đoạn mã của bạn:

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) 

Bây giờ thật dễ dàng để thêm các nút thêm (chỉ cần thêm một entry vào danh sách đầu vào). Nó cũng dễ dàng thay đổi những gì bạn làm cho tất cả các nút bằng cách thay đổi phần thân của vòng lặp for.

+0

Ngoài ra, bạn có thể đặt thông số bằng từ điển lồng nhau: 'bParams = {'button1': {'bg': 'red', 'command' = self.frame.quit, ...}, ... } '.Tôi không chắc chắn nếu bạn có thể thêm các lệnh trong từ điển, nhưng nếu không, bạn có thể làm: 'b = Button (root, văn bản = s, bg = bParams [b], ...)'. –

+0

Ồ, cảm ơn. Điều đó có thể làm việc :) –

6

Để trả lời câu hỏi cụ thể của bạn về việc liệu bạn có thể có một ràng buộc duy nhất áp dụng cho nhiều tiện ích hay không, câu trả lời là có. Nó có thể sẽ dẫn đến nhiều dòng mã hơn là ít hơn, nhưng nó dễ dàng để làm.

Tất cả tiện ích con tkinter đều có tên "bindtags". Bindtags là một danh sách các "thẻ" mà các ràng buộc được đính kèm. Bạn sử dụng tất cả các thời gian mà không biết nó. Khi bạn liên kết với một tiện ích, liên kết không thực sự trên tiện ích con, nhưng trên thẻ có cùng tên với tên cấp thấp của tiện ích con. Các ràng buộc mặc định là trên một thẻ có cùng tên với lớp widget (lớp cơ bản, không nhất thiết là lớp python). Và khi bạn gọi bind_all, bạn đang ràng buộc với thẻ "all".

Điều tuyệt vời về thẻ bắt buộc là bạn có thể thêm và xóa thẻ tất cả những gì bạn muốn. Vì vậy, bạn có thể thêm thẻ của riêng bạn, và sau đó gán các ràng buộc với nó với bind_class (Tôi không biết tại sao các tác giả Tkinter đã chọn tên đó ...).

Điều quan trọng cần nhớ là thẻ liên kết có thứ tự và sự kiện được xử lý theo thứ tự này. Nếu trình xử lý sự kiện trả về chuỗi "break", xử lý sự kiện sẽ dừng trước khi bất kỳ thẻ liên kết còn lại nào đã được kiểm tra cho các ràng buộc.

Kết quả thực tế của việc này là, nếu bạn muốn các ràng buộc khác có thể ghi đè lên các ràng buộc mới này, hãy thêm thẻ liên kết của bạn vào cuối. Nếu bạn muốn các ràng buộc của bạn không thể bị ghi đè bởi các ràng buộc khác, hãy đặt nó ngay từ đầu.

Ví dụ

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

Một chút thêm thông tin về bindtags có thể được tìm thấy trong câu trả lời này: https://stackoverflow.com/a/11542200/7432

Ngoài ra, bindtags phương pháp riêng của mình là tài liệu trên trang effbot Basic Widget Methods trong số những nơi khác.

Các vấn đề liên quan