悬停时 Tkinter 绑定按钮工作不正常

Tkinter bind button work incorrectly when hovering

为什么我的 Tkinter 绑定按钮工作不正常? 当我用鼠标点击开始按钮时,关于按钮会改变! show image

这是我的代码:

import tkinter as tk


class Panel(tk.Tk):

    def __init__(self):
        super().__init__()

        # window config
        self.title('test')
        self.geometry('300x300')
        self.configure(bg='#2b2e37')
 
   
    def btns(self, x, y, text, bg, fg):
        def on_enter(ctx):
            self.btn['background'] = fg
            self.btn['foreground'] = bg
        def on_leave(ctx):
            self.btn['background'] = bg
            self.btn['foreground'] = fg

        
        self.btn = tk.Button(self, text=text, bg=bg, fg=fg, activebackground=fg, activeforeground=bg, border=0, width=42, height=2)
        self.btn.bind('<Enter>', on_enter)
        self.btn.bind('<Leave>', on_leave)
        self.btn.place(x=x, y=y)
        

if __name__ == '__main__':
    window = Panel()
    window.btns(0, 190, 'S T A R T', '#2b2e37', '#56fc03')
    window.btns(0, 230, 'A B O U T', '#2b2e37', '#f5ec42')
    window.mainloop()

我想这是为了我的 oop 代码,我写的很简单并且工作正常。 抱歉我的英语不好

我通过为每个按钮分别编写来修复我的代码。

新代码:

    def btns(self):
        def on_enter1(ctx):
            self.btn1['background'] = '#56fc03'
            self.btn1['foreground'] = '#2b2e37'
        def on_leave1(ctx):
            self.btn1['background'] = '#2b2e37'
            self.btn1['foreground'] = '#56fc03'
        def on_enter2(ctx):
            self.btn2['background'] = '#f5ec42'
            self.btn2['foreground'] = '#2b2e37'
        def on_leave2(ctx):
            self.btn2['background'] = '#2b2e37'
            self.btn2['foreground'] = '#f5ec42'

        
        self.btn1 = tk.Button(self, text='S T A R T', bg='#2b2e37', fg='#56fc03', activebackground='#56fc03', activeforeground='#2b2e37', border=0, width=42, height=2)
        self.btn2 = tk.Button(self, text='A B O U T', bg='#2b2e37', fg='#f5ec42', activebackground='#f5ec42', activeforeground='#2b2e37', border=0, width=42, height=2)
        self.btn1.bind('<Enter>', on_enter1)
        self.btn1.bind('<Leave>', on_leave1)
        self.btn2.bind('<Enter>', on_enter2)
        self.btn2.bind('<Leave>', on_leave2)
        self.btn1.place(x=0, y=190)
        self.btn2.place(x=0, y=230)

if __name__ == '__main__':
    window = Panel()
    window.label()
    window.btns()
    window.mainloop()

事件发生的按钮被传递给 widget 属性中 ctx 参数中的事件处理程序,因此您可以使用它代替 self.btn:

    def btns(self, x, y, text, bg, fg):
        def on_enter(ctx):
            ctx.widget['background'] = fg
            ctx.widget['foreground'] = bg
        def on_leave(ctx):
            ctx.widget['background'] = bg
            ctx.widget['foreground'] = fg

在这些事件处理程序中使用 self.btn 代替 ctx.widget 的问题是,您第二次调用 btns 时,self.btn 被替换为第二个按钮,因此您添加到第一个按钮的事件处理程序最终会更改第二个按钮。