Python/TkInter - Метод определения того, какая кнопка была нажата из сетки кнопок, созданной циклом for

Я пытаюсь сделать очень простую итерацию Othello с Tkinter и Python, и у меня есть идея, однако я не знаю метода, чтобы узнать, какая кнопка нажата (через целое число?). Я сделал сетку кнопок, используя

for x in range(8):
    for y in range(8):
        btn = Button(frame)
        buttons.append(btn)
        btn.grid(column=x, row=y, sticky=N+S+E+W)
        btn.config(bg='green2')

Я планирую настроить кнопки на нажатие и проверить все 8 направлений, добавляя и вычитая значения кнопок, чтобы найти кнопку слева (-8), вверху справа (+7) и т. Д. Я очень новичок в кодирование и хотел бы получить отзывы, спасибо.

2 ответа

Добро пожаловать в SO!

Вы можете создать привязку к любому виджету в tkinter, синтаксис:

widget.bind(sequence, func, add)

Итак, для вашего примера вы можете создать привязку для каждой кнопки и передать значения x и y, которые являются аргументами для отслеживания того, какая кнопка находится в целевой функции. Что-то вроде этого:

btn.bind("<Button-1>", lambda x=x, y=y: print(x, y))

Это напечатает координаты каждой кнопки в сетке, затем вы можете заменить оператор печати любой функцией, которая вам нужна.

Список всех привязок можно найти здесь

Вам не нужно заключать все свое приложение в класс, как это сделал я, или даже иметь статический метод. Важно то, что у вас есть какая-то функция обратного вызова, которая запускается при нажатии кнопки. В рамках вызова этой функции обратного вызова вы также передаете ссылку на объект кнопки, который был нажат в обратном вызове. Есть и другие способы сделать это, но я думаю, что имеет смысл передать ссылку на саму кнопку:

import tkinter as tk


class Application(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.title("Buttons")
        self.resizable(width=False, height=False)

        number_of_rows = 8
        number_of_columns = 8

        for y in range(number_of_rows):
            for x in range(number_of_columns):
                button = tk.Button(self, text=f"{x}, {y}")
                button.config(command=lambda button=button: Application.on_button_click(button))
                button.grid(column=x, row=y)

    @staticmethod
    def on_button_click(button):
        button.config(bg="green")
        print(f"You clicked on {button['text']}")


def main():

    application = Application()
    application.mainloop()

    return 0


if __name__ == "__main__":
    import sys
    sys.exit(main())
Другие вопросы по тегам