команды кнопок tkinter с лямбдой в Python

ive попытался найти решение, но не смог найти тот, который работает. У меня есть 2d-список кнопок tkinter, и я хочу изменить их текст, когда он щелкнет мышью. Я попытался сделать это:

def create_board(number):
    print(number)
    for i in range (0,number):
        buttonList.append([])
        for j in range(0,number):
            print(i,j)
            buttonList[i].append(Button(root, text = " ", command = lambda: update_binary_text(i,j)))
            buttonList[i][j].pack()

затем, когда он нажат, он вызывает эту функцию:

def update_binary_text(first,second):
    print(first,second)
    buttonList[first][second]["text"] = "1"

когда я нажимаю кнопку, она просто ничего не делает, у меня была программа, отображающая индексы кнопки, которая была нажата, и все они показывают 4, 4 (это когда переменная number=5) есть решение проблемы?
это моя первая попытка Python для класса.

спасибо

2 ответов


вы можете исправить эту проблему путем создания для закрытия i и j С созданием каждой лямбды:

command = lambda i=i, j=j: update_binary_text(i, j)

вы также можете создать фабрику обратного вызова со ссылками на сами объекты button:

def callback_factory(button):
    return lambda: button["text"] = "1"

и затем в вашем коде инициализации:

for j in range(0, number):
    new_button = Button(root, text=" ")
    new_button.configure(command=callback_factory(new_button))
    new_button.pack()
    buttonList.append(new_button)

всякий раз, когда мне нужна коллекция подобных виджетов, я нахожу, что проще всего заключить их в объект и передать метод привязки в качестве обратного вызова, а не играть в трюки с лямбда. Итак, вместо того, чтобы иметь список, как buttonList[] С помощью виджетов создайте объект:

class MyButton(object):
    def __init__(self, i, j):
        self.i = i
        self.j = j
        self.button = Button(..., command = self.callback)

    def callback(self):
        . . .

теперь у вас есть список buttonList[] этих объектов, а не сами виджеты. Чтобы обновить текст, либо укажите метод для этого, либо получите доступ к члену напрямую:buttonList[i].button.configure(. . .) и когда обратный вызов активированный, он имеет весь объект и любые атрибуты, которые вам могут понадобиться в self.