К сожалению, похоже, что ОС Windows не запускает настройки виджетов state
и default
должным образом. Однако этого можно достичь, выполнив свои собственные привязки.
Если у вас есть только несколько виджетов, которым требуется такое поведение, вы можете создать оболочку виджета:
def ResponsiveWidget(widget, *args, **kwargs):
bindings = {
'<FocusIn>': {'default':'active'}, # for Keyboard focus
'<FocusOut>': {'default': 'normal'},
'<Enter>': {'state': 'active'}, # for Mouse focus
'<Leave>': {'state': 'normal'}
}
# Create the widget instance
w = widget(*args, **kwargs)
# Set the bindings for the widget instance
for k, v in bindings.items():
w.bind(k, lambda e, kwarg=v: e.widget.config(**kwarg))
# Remember to return the created and binded widget
return w
btn = ResponsiveWidget(tk.Button, root, text='test3', bg="#000000", fg="#ffffff", highlightthickness=10, activebackground="#ffffff",
activeforeground="#000000", highlightbackground='red', highlightcolor='green')
btn2 = ResponsiveWidget(tk.Button, root, text='test4', bg="#000000", fg="#ffffff", highlightthickness=10, activebackground="#ffffff",
activeforeground="#000000", highlightbackground='green', highlightcolor='red')
С другой стороны, если вы хотите, чтобы весь класс виджета всегда правильно запускал состояние по умолчанию / состояние, вместо этого вы можете использовать bind_class
:
bindings = {
'<FocusIn>': {'default':'active'}, # for Keyboard focus
'<FocusOut>': {'default': 'normal'},
'<Enter>': {'state': 'active'}, # for Mouse focus
'<Leave>': {'state': 'normal'}
}
for k, v in bindings.items():
root.bind_class('Button', k, lambda e, kwarg=v: e.widget.config(**kwarg))
Это, кажется, вызывает события просто отлично.
Если вы просто хотите повторить функциональность цвета подсветки, менее желательным методом было бы вместо этого изменить конфигурацию highlightcolor
на фокусе:
bindings = {
'<FocusIn>': {'highlightcolor':'red'},
'<FocusOut>': {'highlightcolor': 'SystemButtonFace'},
'<Enter>': {'state': 'active'},
'<Leave>': {'state': 'normal'}
}
for k, v in bindings.items():
root.bind_class('Button', k, lambda e, kwarg=v: e.widget.config(**kwarg))
# Note this method requires you to set the default='active' for your buttons
btn = tk.Button(root, text='test', bg="#000000", fg="#ffffff", highlightthickness=10, activebackground="#ffffff",
activeforeground="#000000", highlightcolor='SystemButtonFace', default='active')
# ...
Я бы посчитал это более хакерским методом.
Редактировать: Для полноты вот MCVE, использующий bind_class
:
import tkinter as tk
root = tk.Tk()
bindings = {
'<FocusIn>': {'highlightcolor':'red'},
'<FocusOut>': {'highlightcolor': 'SystemButtonFace'},
'<Enter>': {'state': 'active'},
'<Leave>': {'state': 'normal'}
}
for k, v in bindings.items():
root.bind_class('Button', k, lambda e, kwarg=v: e.widget.config(**kwarg))
btns = list(range(5))
for btn in btns:
btns[btn] = tk.Button(root, text='test', bg="#000000", fg="#ffffff", highlightthickness=5, activebackground="#ffffff",
activeforeground="#000000", highlightcolor='SystemButtonFace', default='active', padx=5, pady=5)
btns[btn].pack()
btns[0].focus_set()
root.mainloop()
И MCVE, использующий ResponsiveWidget
функцию:
import tkinter as tk
root = tk.Tk()
def ResponsiveWidget(widget, *args, **kwargs):
bindings = {
'<FocusIn>': {'highlightcolor':'red'}, # for Keyboard focus
'<FocusOut>': {'highlightcolor': 'SystemButtonFace'},
'<Enter>': {'state': 'active'}, # for Mouse focus
'<Leave>': {'state': 'normal'}
}
# Create the widget instance
w = widget(*args, **kwargs)
# Set the bindings for the widget instance
for k, v in bindings.items():
w.bind(k, lambda e, kwarg=v: e.widget.config(**kwarg))
# Remember to return the created and binded widget
return w
btns = list(range(5))
for btn in btns:
btns[btn] = ResponsiveWidget(tk.Button, root, text=f'test{btn}', bg="#000000", fg="#ffffff", highlightthickness=10, activebackground="#ffffff",
activeforeground="#000000", highlightcolor='SystemButtonFace', default='active', padx=5, pady=5)
btns[btn].pack()
btns[0].focus_set()
root.mainloop()