Как эффективно добавить множество кнопок в рамку tkinter? - PullRequest
5 голосов
/ 21 августа 2011

Я хочу добавить 10 кнопок в Tkinter с именем One to Ten. По сути, я просто использовал метод грубой силы, добавляя каждую кнопку по мере необходимости в функцию init класса моего приложения. Это работает, но я хочу минимизировать используемый код, чтобы быть более эффективным, например, используя структуру данных для удержания всех кнопок.

Я думал об использовании buttonBox для удержания всех кнопок, но я не был уверен, смогу ли я манипулировать размещением с помощью grid(), чтобы расположить кнопки так, как я хотел.

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 ]

4 голосов
/ 21 августа 2011

Вместо того, чтобы называть кнопки self.one, self.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 голос
/ 21 августа 2011

Вы можете поместить все свойства кнопок в dict, а затем зациклить его, чтобы создать свои кнопки, вот пример:

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)

Это также позволит вам легко добавлять новые кнопки при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...