Python Tkinters突出显示按钮对我不起作用

Python Tkinters突出显示按钮对我不起作用,python,tkinter,Python,Tkinter,根据关于使用.configure(highlightbackground='red')的公认答案,按钮上的应在按钮周围应用颜色,但在测试中,我无法再现海报在gif录制中显示的内容 这是我的测试用例:(注意,即使复制粘贴海报代码,我也无法获得它们显示的突出效果) 结果应用程序: 通过广泛的搜索,我没有在同一问题的Q/A方面找到太多的highlightbackground,因此可能遗漏了一些东西。我还尝试将焦点设置为小部件需要焦点的状态,并且具有相同的非结果 可能是版本或操作系统相关的 操作系统-

根据关于使用
.configure(highlightbackground='red')
的公认答案,按钮上的
应在按钮周围应用颜色,但在测试中,我无法再现海报在gif录制中显示的内容

这是我的测试用例:(注意,即使复制粘贴海报代码,我也无法获得它们显示的突出效果)

结果应用程序:

通过广泛的搜索,我没有在同一问题的Q/A方面找到太多的
highlightbackground
,因此可能遗漏了一些东西。我还尝试将焦点设置为小部件需要焦点的状态,并且具有相同的非结果

可能是版本或操作系统相关的

操作系统-Windows10Pro

Python-3.6.2

使用Krrr的帖子更新了示例。因此,这确实是一种工作,但现在的问题是,它是调整按钮的大小,而不是提供正确的突出显示的颜色

import tkinter as tk


def ResponsiveWidget(widget, *args, **kwargs):
    bindings = {
        '<FocusIn>': {'highlightbackground': 'red', 'highlightcolor':'red'},
        '<FocusOut>': {'highlightbackground': '#d9d9d9', '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))


def update_active(event):
    global previous_button
    if previous_button != event.widget:
        previous_button.config(default='normal')
        event.widget.config(default='active')
        previous_button = event.widget


root = tk.Tk()
button_list = []
previous_button = None

for i in range(5):
    if i == 0:
        button_list.append(tk.Button(root, text='test', bg="#000000", fg="#ffffff", highlightthickness=5,
                                     activebackground="#ffffff", activeforeground="#000000", default='active'))
        previous_button = button_list[-1]
    else:
        button_list.append(tk.Button(root, text='test', bg="#000000", fg="#ffffff", highlightthickness=5,
                                     activebackground="#ffffff", activeforeground="#000000", default='normal'))
    button_list[-1].pack(padx=5, pady=5)
    button_list[-1].bind('<ButtonRelease-1>', update_active)

root.mainloop()
将tkinter作为tk导入
def响应小部件(小部件,*args,**kwargs):
绑定={
'':{'highlightbackground':'red','highlightcolor':'red'},
'':{'highlightbackground':'#d9d9d9','highlightcolor':'SystemButtonFace'},
'':{'state':'active'},
'':{'state':'normal'}
}
对于bindings.items()中的k,v:
root.bind_类('Button',k,lambda e,kwarg=v:e.widget.config(**kwarg))
def更新_激活(事件):
全局上一个按钮
如果上一个_按钮!=event.widget:
previous_button.config(默认值='normal')
event.widget.config(默认值='active')
上一个按钮=event.widget
root=tk.tk()
按钮列表=[]
上一个按钮=无
对于范围(5)中的i:
如果i==0:
按钮列表追加(tk.按钮(root,text='test',bg=“#000000”,fg=“#ffffff”,highlightthickness=5,
activebackground=“#ffffff”,activeforeground=“#000000”,默认值为“活动”)
上一个按钮=按钮列表[-1]
其他:
按钮列表追加(tk.按钮(root,text='test',bg=“#000000”,fg=“#ffffff”,highlightthickness=5,
activebackground=“#ffffff”,activeforeground=“#000000”,default='normal'))
按钮列表[-1]。打包(padx=5,pady=5)
按钮列表[-1]。绑定(“”,更新活动)
root.mainloop()
结果:

期望:


不幸的是,Windows操作系统似乎没有触发
状态
,并且
默认
小部件配置正确。但是,这可以通过自己的绑定来实现

如果只有少数小部件需要此行为,则可以创建小部件包装器:

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')
这似乎很好地触发了事件

如果您只想复制高光颜色的功能,一种不太理想的方法是更改焦点上的
highlightcolor
config:

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使用
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()
将tkinter作为tk导入
root=tk.tk()
def响应小部件(小部件,*args,**kwargs):
绑定={
'':{'highlightcolor':'red'},#用于键盘焦点
'':{'highlightcolor':'SystemButtonFace'},
'':{'state':'active'},#用于鼠标焦点
'':{'state':'normal'}
}
#创建小部件实例
w=widget(*args,**kwargs)
#设置小部件实例的绑定
对于bindings.items()中的k,v:
w、 绑定(k,lambda e,kwarg=v:e.widget.config(**kwarg))
#记住返回已创建和绑定的小部件
返回w
基站=列表(范围(5))
对于btn中的btn:
btn[btn]=ResponsiveWidget(tk.Button,root,text=f'test{btn}),bg=“#000000”,fg=“#ffffff”,highlightthickness=10,activebackground=“#ffffff”,
activeforeground=“#000000”,highlightcolor='SystemButtonFace',默认='active',padx=5,pady=5)
基站[btn].pack()
基站[0]。焦点集()
root.mainloop()

您的代码在OSX上运行:我看到红色高亮显示颜色。@BryanOakley哼。不在我的工作电脑上工作。我回家后会在3.7上测试。值得一提的是,它也不在我的Windows 10 Python 3.7.4上工作。我认为你不会有什么好运气。似乎与操作系统有关。@Krrr感谢您的输入。在这一点上,这听起来像是一个操作系统的问题。我要补充一个观察——按钮的大小对我来说似乎是可疑的。在您链接到的答案上,按钮之间有间距,但是当我运行代码时,按钮会被扩展到最大,没有间距。与您当前的示例相同。哼。除非我使用
focus()
,否则我只能得到多个没有边框的按钮。这个想法是在点击按钮时高亮显示会发生变化。你的意思是你想在焦点移开时显示
highlightbackground
颜色?是的,那一点我也想弄清楚,不知道为什么那个特定的设置没有被触发。这是主要的斗争。我已经在lambda中添加了一个打印语句,用于测试它可能有助于故障排除
w.bind(k,lambda e,kwarg=v:(e.widget.config(**kwarg),print('test{}-{}.format(e,kwarg)))
因此目标是复制本文的预期功能。如果你需要的只是功能,一个肮脏的方法是保持按钮的
default='active'
,只需在焦点上更改
highlighcolor
,它将达到同样的效果,尽管不是预期的方法。
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')

# ...
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()
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()