Как мне каждый раз получать доступ к другой кнопке в Tkinter? - PullRequest
2 голосов
/ 14 октября 2019

У меня есть девять кнопок, созданных следующим образом:

MyButton1 = Button(game, text="BUTTON1", image=pixel, compound="c", width=200, height=200, command=callback(1))
MyButton1.grid(row=0, column=0)

MyButton2 = Button(game, text="BUTTON2", image=pixel, compound="c", width=200, height=200, command=callback(2))
MyButton2.grid(row=1, column=0)

MyButton3 = Button(game, text="BUTTON3", image=pixel, compound="c", width=200, height=200, command=callback(3))
MyButton3.grid(row=2, column=0)

# and so on

Я хочу изменить текст конкретной кнопки при ее нажатии, и я знаю, что button.config можно использовать для изменения некоторых вещей вкнопка. Например, если бы я хотел изменить текст на MyButton1, я мог бы сделать что-то вроде этого: MyButton1.config(text="X"). Но я думаю, что было бы довольно грязно иметь разные функции для command для каждой кнопки, поэтому я мог бы создать такую ​​функцию:

def callback(id):
    print(id)
    # change the text of the button

Но моя проблема в том, что я незнать, как получить доступ к кнопке, когда кнопка, которую я пытаюсь получить, отличается каждый раз. Я не могу сделать "MyButton" + str(id).config по понятным причинам (это строка). Так как мне это сделать?

Ответы [ 2 ]

2 голосов
/ 14 октября 2019

Используйте список кнопок. Вы можете ссылаться на индекс в лямбда-команде.

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

Важно отметить, что вы не можете просто выполнить command= update_button(x), так как это вызовет функцию, экземпляр которой кнопка создана, а не ожидаетдля вас, чтобы нажать его. Это потому, что в команде мы вызывали функцию вместо сохранения ссылки на нее. Чтобы сохранить ссылку на функцию, мы просто опускаем круглые скобки, такие как command= update_button.

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

import tkinter as tk


def update_button(ndex):
    button_list[ndex].config(text='x')


root = tk.Tk()

button_list = []
for i in range(9):
    button_list.append(tk.Button(root, text='Button {}'.format(i), command=lambda x=i: update_button(x)))
    button_list[-1].pack(fill='x')

root.mainloop()

Приложение результатов, в котором были нажаты несколько кнопок:

enter image description here

Вот пример использования сетки с некоторой математикой для обработки размещения сетки в столбцах и строках.

import tkinter as tk


def update_button(ndex):
    button_list[ndex].config(text='x')


root = tk.Tk()

button_list = []
row = 0
column = 0
for i in range(15):
    button_list.append(tk.Button(root, text='Button {}'.format(i+1), command=lambda x=i: update_button(x)))
    button_list[-1].grid(row=row, column=column, sticky='ew')
    if row % 4 == 0 and row != 0:
        column += 1
        row = 0
    else:
        row += 1

root.mainloop()

Результаты:

enter image description here

Если вы предпочитаете сначала запускать столбцы, то строки просто переворачивают математику:

if column % 4 == 0 and column != 0:
    row += 1
    column = 0
else:
    column += 1

Результаты:

enter image description here

2 голосов
/ 14 октября 2019

Сначала определите кнопку, а затем поместите ее в обратный вызов, например,

def changetext(button):
  button.config(text="Changed text")

b = Button(master, text="Text here")
b.config(command=lambda button=b: changetext(button))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...