Проблема в том, что tkinter
может связывать многие функции с событием, и уже есть привязанная функция по умолчанию, которая изменилась relief
при нажатии кнопки. Вы можете использовать return "break"
в своей функции, чтобы сообщить tkinter
, что вы обработали это событие, и оно пропустит другие функции.
Или вы можете использовать стандартный command=
для функции проверки, а затем он пропустит другую функцию .
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def selected1(event):
event.widget.config(relief='sunken' if event.widget.cget('relief') == 'raised' else 'raised')
return "break"
def selected2():
B2.config(relief='sunken' if B2.cget("relief") == 'raised' else 'raised')
# --- main ---
root = tk.Tk()
B1 = tk.Button(root, text='BUTTON1', relief='raised')
B1.bind("<Button>", selected1)
B1.grid(row=1, column=2, sticky='news')
B2 = tk.Button(root, text='BUTTON2', relief='raised', command=selected2)
B2.grid(row=2, column=2, sticky='news')
root.mainloop()
То же, используя for
-l oop и lambda
.
Обычно используется только ссылка на button
, значение которого изменяется в l oop поэтому, наконец, все функции используют ссылку на одно и то же значение - последнее значение, присвоенное в l oop.
Используя lambda arg=button
, он создает новую переменную в каждом l oop и копирует значение из button
в arg
, поэтому каждый виджет использует разные аргументы с разными значениями.
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def selected(widget):
widget.config(relief='sunken' if widget.cget('relief') == 'raised' else 'raised')
# --- main ---
root = tk.Tk()
for x in range(1, 6):
button = tk.Button(root, text=f'LOOP BUTTON {x}', relief='raised')
#button.config(command=lambda arg=button:selected3(arg))
button['command'] = lambda arg=button:selected(arg)
button.grid(row=x, column=2, sticky='news')
root.mainloop()
Как указано в комментарии @ acw1668, вы также можете использовать Checkbutton(..., indicator=False)
, чтобы получить тот же эффект без дополнительной функции
import tkinter as tk # PEP8: `import *` is not preferred
# --- main ---
root = tk.Tk()
for x in range(1, 6):
button = tk.Checkbutton(root, text=f'LOOP BUTTON {x}', indicator=False, padx=10, pady=5)
button.grid(row=x, column=2, sticky='news')
root.mainloop()