如何高效地向tkinter框架中添加大量按钮?

6
我希望在Tkinter中添加10个按钮,分别命名为One到Ten。我基本上采用了一种蛮力的方法,在我的应用程序类的init函数中逐个添加每个按钮。虽然它能够正常工作,但我希望最小化所需的代码以提高效率,例如使用数据结构来容纳所有按钮。
我考虑使用来容纳所有按钮,但我不确定是否可以通过操纵其中的放置方式以使按钮呈现出我所期望的位置。
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)

有没有人能向我展示一种更有效的方法,比如使用数据结构?

2个回答

5

将按钮命名为self.oneself.two等,比起通过索引列表self.button更方便进行引用。

如果这些按钮有不同的功能,那么你需要显式地将按钮与回调函数关联。例如:

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)

如果按钮的功能都相似,那么一个回调函数就足够服务所有按钮了。由于回调函数本身不能带参数,所以可以设置回调工厂通过闭包传递参数:

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
谢谢!这个方法可行,但我不得不将它改为 "self.button.append()",这样就不会引起 IndexError 了。而且最后一行我改成了 self.button[i].grid(),而不是 self.one.grid()。它完美地运行了 :) - thatbennyguy
只有一件事...你如何让按钮回调不同的命令? - thatbennyguy

1
你可以将所有按钮的属性放在一个字典中,然后循环创建按钮,这里是一个示例:
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)

这也可以让您在需要时轻松添加新的按钮。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接