【问题标题】:Highlighting the selected button in tkinter在 tkinter 中突出显示选定的按钮
【发布时间】:2021-03-12 02:24:46
【问题描述】:

我正在尝试在按钮上切换activebackgroundactiveforeground 的参数。但是,当尝试在选择按钮后更改背景颜色和文本字体并将这些设置重置为之前的状态时,如果单击任何其他按钮并且再次单击的按钮背景颜色和字体不会更改。

例如在上面的屏幕截图中,“对话历史记录”被选中,因此它是灰色加粗字体,所有其他菜单项都是普通字体。如果我点击“重要”,那么“重要”按钮就会变成灰色和粗体。渲染菜单的代码如下:

import tkinter as tk

root = tk.Tk()

def abc:
  #this part is not running 

def ResponsiveWidget(widget, *args, **kwargs):
    bindings = {'<Enter>': {'state': 'active'},
                '<Leave>': {'state': 'normal'}}

    w = widget(*args, **kwargs)

    for (k, v) in bindings.items():
        w.bind(k, lambda e, kwarg=v: e.widget.config(**kwarg))

    return w


button1 = ResponsiveWidget(
    tk.Button,
    root,
    text='abc',
    fg='black',
    activebackground='#B7E3F9',
    activeforeground='black',
    highlightthickness=0,
    relief='flat',
    )
button1.place(x=0, y=50)

button2 = ResponsiveWidget(
    tk.Button,
    root,
    text='xyz',
    fg='black',
    activebackground='#B7E3F9',
    activeforeground='black',
    highlightthickness=0,
    relief='flat',command=lambda: abc
    )   #abc is not calling
button2.place(x=0, y=80)

root.mainloop()

新代码:

import tkinter as tk

root = tk.Tk()

selected_button = None
last_bg = None

def abc():
    print("abc")  #Not executing this part

def change_selected_button(button):
    global selected_button, last_bg
    if selected_button is not None:
        selected_button.config(bg=last_bg)
    selected_button = button
    last_bg = button.cget("bg")
    button.config(bg="orange")

def ResponsiveWidget(widget, *args, **kwargs):
    bindings = {'<Enter>': {'state': 'active'},
                '<Leave>': {'state': 'normal'}}

    w = widget(*args, **kwargs)

    for (k, v) in bindings.items():
        w.bind(k, lambda e, kwarg=v: e.widget.config(**kwarg))

    return w


button1 = ResponsiveWidget(
    tk.Button,
    root,
    text='abc',
    fg='black',
    activebackground='#B7E3F9',
    activeforeground='black',
    highlightthickness=0,
    relief='flat',
    )
button1.place(x=0, y=50)
button1.config(command=lambda button=button1: change_selected_button(button))

button2 = ResponsiveWidget(
    tk.Button,
    root,
    text='xyz',
    fg='black',
    activebackground='#B7E3F9',
    activeforeground='black',
    highlightthickness=0,
    relief='flat',command=abc
    )  
button2.place(x=0, y=80)
button2.config(command=lambda button=button2: change_selected_button(button))



root.mainloop()

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    试试这个:

    import tkinter as tk
    
    def abc():
        print("abc")
    
    def change_selected_button(button):
        abc()
        global selected_button
        if selected_button is not None:
            selected_button.config(bg="white")
        button.config(bg="light blue")
        selected_button = button
    
    root = tk.Tk()
    selected_button = None
    for i in range(5):
        button = tk.Button(root, text="Click me")
        button.pack()
        button.config(command=lambda button=button: change_selected_button(button))
    root.mainloop()
    

    它使用蓝色背景的全局变量selected_button。当按下一个新按钮时,selected_button 中的按钮将被重置,并将新按钮放入变量中。

    这是您在代码中实现它的方式:

    import tkinter as tk
    
    root = tk.Tk()
    
    selected_button = None
    last_bg = None
    
    def abc():
        print("abc")
    
    def change_selected_button(button):
        abc()
        global selected_button, last_bg
        if selected_button is not None:
            selected_button.config(bg=last_bg)
        selected_button = button
        last_bg = button.cget("bg")
        button.config(bg="orange")
    
    def ResponsiveWidget(widget, *args, **kwargs):
        bindings = {'<Enter>': {'state': 'active'},
                    '<Leave>': {'state': 'normal'}}
    
        w = widget(*args, **kwargs)
    
        for (k, v) in bindings.items():
            w.bind(k, lambda e, kwarg=v: e.widget.config(**kwarg))
    
        return w
    
    
    button1 = ResponsiveWidget(
        tk.Button,
        root,
        text='abc',
        fg='black',
        activebackground='#B7E3F9',
        activeforeground='black',
        highlightthickness=0,
        relief='flat',
        )
    button1.place(x=0, y=50)
    button1.config(command=lambda button=button1: change_selected_button(button))
    
    button2 = ResponsiveWidget(
        tk.Button,
        root,
        text='xyz',
        fg='black',
        activebackground='#B7E3F9',
        activeforeground='black',
        highlightthickness=0,
        relief='flat'
        )   #abc is not calling
    button2.place(x=0, y=80)
    button2.config(command=lambda button=button2: change_selected_button(button))
    
    button3 = ResponsiveWidget(
        tk.Button,
        root,
        text='test',
        fg='black',
        activebackground='#B7E3F9',
        activeforeground='black',
        highlightthickness=0,
        relief='flat'
        )   #abc is not calling
    button3.place(x=0, y=110)
    button3.config(command=lambda button=button3: change_selected_button(button))
    
    root.mainloop()
    

    【讨论】:

    • 谢谢。 @TheLizzard
    • 我使用了这个,但是需要通过单击按钮运行的功能不起作用。我的意思是我们在按钮内给出的命令不起作用。只有 button.config 命令有效。请查看更新后的问题并提出建议。 @TheLizzard
    • @Jung-suk 它会给你一个错误吗?你在用lambda button=button: change_selected_button(button)吗?
    • 否,但如上例所示,如果我单击按钮,它不会调用函数 abc。 @TheLizzard
    • @Jung-suk 在change_selected_button 函数的开头添加abc()。我改变了我的答案。
    猜你喜欢
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多