开发者

How can I add a lot of Buttons to the tkinter Frame efficiently?

I want to add 10 buttons to Tkinter, named One to Ten. I basically just used the brute force method, adding each button as I went, in the init function of my application's class. It work开发者_如何学Cs, but I want to minimize the code used, to be more efficient, such as using a data structure to hold all the buttons.

I was thinking of using a buttonBox to hold all the buttons in, but I was not sure if I could manipulate the placement via grid() to place the buttons how I wanted.

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)

Can anyone show me a way to make this more efficient, such as a data structure?


Instead of naming the buttons self.one, self.two, etc., it would be more convenient to refer to them by indexing a list, such as self.button.

If the buttons do different things, then you just have to explicitly associate buttons with callbacks. For example:

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)

If the buttons all do similar things, then one callback may suffice to service them all. Since the callback itself can't take arguments, you can setup a callback factory to pass the arguments in through a closure:

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)


You could put all the buttons properties in a dict, and then loop on it to create your buttons, here is an example:

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)

This would also allow you to easily add new buttons if needed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜