如何实现Tkinter透明粉色Overlay的点击穿透功能?
实现Tkinter透明覆盖层的点击穿透功能
要让透明粉色覆盖层可见且点击可穿透至后台应用,Tkinter本身无直接支持,但Windows系统下可通过调用Win32 API设置窗口扩展样式实现,同时需要优化定时器逻辑避免阻塞界面。
步骤1:安装依赖
先安装pywin32库用于调用Windows API:
pip install pywin32
步骤2:修改后的完整代码
import tkinter as tk from tkinter import messagebox import win32gui import win32con win = tk.Tk() win.title("Pink-Out") win.geometry("1900x1000") win.configure(bg='black') # 初始化时间变量 sec = tk.StringVar(value='00') mins = tk.StringVar(value='00') hrs = tk.StringVar(value='00') # 创建时间输入控件 sec_entry = tk.Entry(win, textvariable=sec, width=2, font='Helvetica 14') sec_entry.place(x=1720, y=900) mins_entry = tk.Entry(win, textvariable=mins, width=2, font='Helvetica 14') mins_entry.place(x=1680, y=900) hrs_entry = tk.Entry(win, textvariable=hrs, width=2, font='Helvetica 14') hrs_entry.place(x=1640, y=900) # 创建开始按钮 start_btn = tk.Button(win, text='START', bd='2', bg='IndianRed1', font=('Helvetica bold',10)) start_btn.place(x=2667, y=925) def set_clickthrough(hwnd): # 设置窗口扩展样式,实现点击穿透 ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) ex_style |= win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, ex_style) def update_timer(times): if times < 0: # 时间归零后重置为20分钟并提示休息 sec.set('00') mins.set('20') hrs.set('00') messagebox.showinfo("", "Take a break") # 继续循环计时 new_times = 20 * 60 win.after(1000, update_timer, new_times - 1) return # 计算当前时分秒 hour = times // 3600 minute = (times % 3600) // 60 second = times % 60 # 更新时间显示(补零) sec.set(f"{second:02d}") mins.set(f"{minute:02d}") hrs.set(f"{hour:02d}") # 1秒后递归更新 win.after(1000, update_timer, times - 1) def pink(): # 隐藏控制控件 start_btn.place_forget() sec_entry.place_forget() mins_entry.place_forget() hrs_entry.place_forget() # 设置覆盖层窗口属性 win.configure(bg='#FF007F') win.attributes('-fullscreen', True) win.attributes('-alpha', 0.10, '-topmost', 1) # 配置点击穿透 hwnd = win32gui.FindWindow(None, win.title()) set_clickthrough(hwnd) messagebox.showinfo("", "Remember to look away from your screen every 20 min to protect your eyes.") # 获取初始计时时长并启动定时器 initial_times = int(hrs.get())*3600 + int(mins.get())*60 + int(sec.get()) update_timer(initial_times) start_btn.config(command=pink) win.bind('<Return>', lambda event: pink()) win.mainloop()
核心优化说明
- 点击穿透实现:通过
win32gui给窗口添加WS_EX_TRANSPARENT扩展样式,让窗口完全忽略鼠标事件,点击直接传递给后台应用 - 定时器优化:用Tkinter原生的
after()替代time.sleep()和while循环,避免阻塞主循环导致界面卡顿无响应 - 界面整理:启动覆盖层后隐藏控制按钮和输入框,避免遮挡视线
- 跨平台提示:此方案仅适配Windows系统,若需支持Linux/macOS,需使用对应平台的窗口管理API(如Linux的Xlib、macOS的Quartz)
内容的提问来源于stack exchange,提问作者Neatdonkey
相关产品推荐
相关产品推荐

