2011-08-21 31 views
5

Tôi muốn thêm 10 nút vào Tkinter, có tên là Một đến Mười. Về cơ bản, tôi chỉ sử dụng phương pháp bạo lực, thêm mỗi nút như tôi đã đi, trong hàm init của lớp ứng dụng của tôi. Nó hoạt động, nhưng tôi muốn giảm thiểu mã được sử dụng, để có hiệu quả hơn, chẳng hạn như sử dụng cấu trúc dữ liệu để giữ tất cả các nút.Làm cách nào để thêm nhiều Nút vào khung tkinter một cách hiệu quả?

Tôi đã nghĩ đến việc sử dụng buttonBox để giữ tất cả các nút trong, nhưng tôi không chắc liệu mình có thể thao tác vị trí qua grid() để đặt các nút theo cách mình muốn hay không.

self.one = Button(frame, text="One", command=self.callback) 
self.one.grid(sticky=W+E+N+S, padx=1, pady=1) 

self.two = Button(frame, text="Two", command=self.callback) 
self.two.grid(sticky=W+E+N+S, row=0, column=1, padx=1, pady=1) 

self.three = Button(frame, text="Three", command=self.callback) 
self.three.grid(sticky=W+E+N+S, row=0, column=2, padx=1, pady=1) 

# ... 

self.ten = Button(frame, text="Ten", command=self.callback) 
self.ten.grid(sticky=W+E+N+S, row=1, column=4, padx=1, pady=1) 

Bất kỳ ai cũng có thể chỉ cho tôi cách làm hiệu quả hơn, chẳng hạn như cấu trúc dữ liệu?

Trả lời

4

Thay vì đặt tên các nút self.one, self.two, v.v., sẽ thuận tiện hơn khi tham khảo chúng bằng cách lập chỉ mục danh sách, chẳng hạn như self.button.

Nếu các nút làm khác nhau điều, thì bạn chỉ cần rõ ràng nút liên kết với gọi lại. Ví dụ:

name_callbacks=(('One',self.callback_one), 
       ('Two',self.callback_two), 
       ..., 
       ('Ten',self.callback_ten)) 
self.button=[] 
for i,(name,callback) in enumerate(name_callbacks): 
    self.button.append(Button(frame, text=name, command=callback)) 
    row,col=divmod(i,5) 
    self.button[i].grid(sticky=W+E+N+S, row=row, column=col, padx=1, pady=1) 

Nếu các nút tất cả làm tương tự vật, sau đó người ta gọi lại có thể đủ để phục vụ tất cả. Kể từ khi gọi lại chính nó không thể lấy đối số, bạn có thể thiết lập một nhà máy gọi lại để vượt qua các đối số trong thông qua một kết thúc:

def callback(self,i): # This is the callback factory. Calling it returns a function. 
    def _callback(): 
     print(i) # i tells you which button has been pressed. 
    return _callback 

def __init__(self): 
    names=('One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten') 
    self.button=[] 
    for i,name in enumerate(names): 
     self.button.append(Button(frame, text=name, command=self.callback(i+1))) 
     row,col=divmod(i,5) 
     self.button[i].grid(sticky=W+E+N+S, row=row, column=col, padx=1, pady=1) 
+1

Cảm ơn bạn! Điều này làm việc, nhưng tôi đã phải thay đổi nó thành "self.button.append()" để nó không gây ra một IndexError. Và dòng dưới cùng tôi đã thay đổi thành self.button [i] .grid(), thay vì self.one.grid(). Nó hoạt động hoàn hảo :) – thatbennyguy

+0

@thatbennyguy: Ack! Cảm ơn bạn đã sửa! – unutbu

+0

Chỉ có một điều ... làm thế nào bạn sẽ nhận được các nút để gọi lại các lệnh khác nhau? – thatbennyguy

1

Bạn có thể đặt tất cả các nút thuộc tính trong một dict, rồi vòng vào nó để tạo các nút của bạn, đây là một ví dụ:

buttons = { 
    'one': {'sticky': W+E+N+S, 'padx': 1, 'pady': 1}, 
    'two': {'sticky': W+E+N+S, 'row': 0, 'column': 1, 'padx': 1, 'pady': 1}, 
    'three': {'sticky': W+E+N+S, 'row': 0, 'column': 2, 'padx': 1, 'pady': 1} 
} 
for b in buttons: 
    button = Button(frame, text=b.title(), command=self.callback) 
    button.grid(**buttons[b]) 
    setattr(self, b, button) 

Điều này cũng sẽ cho phép bạn dễ dàng thêm các nút mới nếu cần.

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