You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter如何检测鼠标在按钮外部释放并避免异常变色

问题根因

高亮变色逻辑绑定在<Button-1>(鼠标按下事件)上,只要鼠标在按钮上按下就立刻触发变色,但Tkinter按钮原生command回调的触发规则为按钮范围内按下+按钮范围内松开才会执行,二者触发逻辑不一致就出现了异常高亮的问题。

修复步骤

  1. 把变色触发事件从按下改为<ButtonRelease-1>(鼠标松开事件),同时增加鼠标位置校验,仅当松开时指针仍在按钮范围内才执行高亮逻辑
  2. 修复原代码中的笔误:未声明的B1ButtonCls改为自定义的TypeButton、不存在的容器self.frame_1改为self.frame、调整回调函数参数兼容事件绑定要求

修复后完整可运行代码

from tkinter import *

class TypeButton(Button):
    def __init__(self, parent, *args, **kwargs):
        kwargs = {'font':('Calibri',9,'bold'), 'bg': '#11161d', 'fg':'white',
                  'width':10, 'bd':0, 'activebackground':'#bdfe04', **kwargs}
        super().__init__(parent, *args, **kwargs)

class Example(Frame):
    def __init__(self,parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.frame = Frame(self, bg='#11161d')
        self.frame.grid(padx=(10,10), pady=(6,6))
        self.container1 = None

        self.creator_buttons()
        self.bind_all("<B1-Motion>", self.callback)

    def creator_buttons(self):  

        mobiles = [['Frog', 'Fox', 'Boomer', 'Ice', 'J.d', 'Grub', 'Lightning', 'Aduka', 'Knight', 'Kalsiddon', 'Mage'],
                   ['Randomizer', 'Jolteon', 'Turtle', 'Armor', 'A.sate', 'Raon', 'Trico', 'Nak', 'Bigfoot', 'Barney', 'Dragon']]                
        self.mobiles2 = ['Fox','Knight','Jolteon','Barney','Dragon'] 

        self.buttons22 = []
        for index1, mobil in enumerate(mobiles):
            for index2, texto in enumerate(mobil):
                btn = TypeButton(self.frame, text=texto, command= self.callback)            
                n1 = 5 if index2 == 0 else 0        
                n2 = 5 if index2 == 10 else 0
                btn.grid(column=index2 , row=index1 , pady=3, padx=(n1,n2))

                btn.bind("<Enter>", self.enter_mouse)
                btn.bind("<Leave>", self.leave_mouse)
                # 把按下事件改成松开事件
                btn.bind("<ButtonRelease-1>", self.clic_mouse)

                if texto in self.mobiles2: btn.config(fg='yellow')
                self.buttons22.append(btn)   

    def enter_mouse(self, event):
        widget1 = event.widget
        if not widget1.cget('bg') == '#bdfe04': 
            widget1.config(bg="#24364a")

    def leave_mouse(self, event):
        if not event.widget.cget('bg') == '#bdfe04':
            event.widget.config(bg='#11161d')                               

    def clic_mouse(self, event):
        widget1 = event.widget
        # 新增校验:仅当松开时鼠标仍在按钮范围内才触发变色
        if 0 <= event.x < widget1.winfo_width() and 0 <= event.y < widget1.winfo_height():
            widget1.config(bg='#bdfe04', fg='black')
            
            if self.container1 is not None and self.container1 != widget1:
                if self.container1.cget('text') in self.mobiles2:
                    self.container1.config (bg='#11161d', fg='yellow')
                else:
                    self.container1.config (bg='#11161d', fg='white')          
            self.container1 = widget1
    
    # 增加*args兼容事件绑定的参数传入
    def callback(self, *args):
        print('Closed')
 
root = Tk()
app = Example(root).pack()
root.mainloop()

内容的提问来源于stack exchange,提问作者Benjamin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:24:05