Python tkinter透明窗口如何正确捕获鼠标进出事件
问题原因
使用wm_attributes("-transparent", 'green')设置透色透明时,Windows系统会自动为窗口添加WS_EX_TRANSPARENT扩展样式,该样式会让透明区域的所有鼠标事件直接透传给下方的窗口,tkinter本身无法捕获到透明区域的<Enter>、<Leave>等鼠标事件,因此绑定的回调函数不会触发。
修复方案
通过Windows API手动修改窗口扩展样式,移除导致鼠标穿透的WS_EX_TRANSPARENT标记,既保留毛玻璃透明效果,又让窗口可以正常接收鼠标事件。
修正后的可运行代码:
from tkinter import * from ctypes import windll, c_int from BlurWindow.blurWindow import blur # Windows API 相关常量定义 GWL_EXSTYLE = -20 WS_EX_LAYERED = 0x80000 WS_EX_TRANSPARENT = 0x20 root = Tk() root.config(bg='green') root.geometry('500x400') root.update() hWnd = windll.user32.GetForegroundWindow() # 应用毛玻璃效果 blur(hWnd) # 修改窗口扩展样式:保留分层窗口属性,移除鼠标穿透属性 ex_style = windll.user32.GetWindowLongW(hWnd, GWL_EXSTYLE) fixed_style = (ex_style | WS_EX_LAYERED) & ~WS_EX_TRANSPARENT windll.user32.SetWindowLongW(hWnd, GWL_EXSTYLE, c_int(fixed_style)) def enter_event(e): print("鼠标进入窗口") def leave_event(e): print("鼠标离开窗口") root.bind("<Enter>", enter_event) root.bind("<Leave>", leave_event) root.mainloop()
注意事项
- 移除
root.wm_attributes("-transparent", 'green')这行代码,该配置是导致鼠标事件失效的核心原因,BlurWindow库的毛玻璃效果本身不需要依赖这个透色设置。 - 如果需要调整窗口整体透明度,可以使用
root.wm_attributes("-alpha", 透明度值)配置,范围为0~1,该配置不会导致鼠标事件穿透。 - 获取窗口句柄的逻辑需要放在
root.update()之后执行,确保窗口已经完成创建能拿到正确的hWnd值。
内容的提问来源于stack exchange,提问作者Ayan Sarkar
相关产品推荐
相关产品推荐

