Tkinter实现:无特定事件触发则几秒后自动销毁窗口
实现焦点切换时的Tkinter提示窗口(带自动隐藏与事件取消)
没问题,我帮你搞定这个需求!核心思路是用Tkinter的after()方法设置自动隐藏的定时器,每次检测到i3窗口焦点切换时,先取消之前的定时器,更新窗口内容并重新显示,再设置新的定时器。这样就能实现“显示后几秒自动隐藏,有新事件则取消隐藏”的效果。
关键实现要点
- 定时器管理:用一个变量存储定时器ID,方便后续用
after_cancel()取消未执行的隐藏操作 - 窗口复用:用
withdraw()和deiconify()来隐藏/显示窗口,比销毁后重建更高效 - i3事件监听:绑定
window::focus事件,每次焦点切换都触发窗口更新逻辑
完整代码
#!/usr/bin/env python import i3ipc import tkinter as tk # 自定义配置项 WINDOW_WIDTH = 150 WINDOW_HEIGHT = 50 AUTO_HIDE_DELAY = 3000 # 自动隐藏延迟(毫秒),这里设为3秒 WINDOW_POSITION = "+100+100" # 窗口显示位置(x+y坐标) # 初始化i3连接与Tk窗口 i3 = i3ipc.Connection() root = tk.Tk() root.title("Focus Indicator") # 优化窗口样式:置顶、无边框、自定义背景 root.attributes("-topmost", True) # 窗口始终在最上层 root.overrideredirect(True) # 去掉默认窗口边框 root.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}{WINDOW_POSITION}") root.configure(bg="#2d3748") # 深色背景,可自行调整 # 创建显示窗口名称的标签 window_label = tk.Label( root, text="", font=("Segoe UI", 12), bg="#2d3748", fg="#f7fafc", padx=10, pady=5 ) window_label.pack(fill=tk.BOTH, expand=True) timer_id = None # 存储定时器ID,用于取消自动隐藏 def update_focus_display(_): """处理焦点切换事件,更新窗口内容并重置定时器""" global timer_id # 取消之前的自动隐藏定时器(如果存在) if timer_id is not None: root.after_cancel(timer_id) timer_id = None # 获取当前聚焦窗口的名称 focused_window = i3.get_tree().find_focused() window_name = focused_window.name if focused_window.name else "Unknown Window" # 更新标签文本并显示窗口 window_label.config(text=window_name) root.deiconify() # 设置新的自动隐藏定时器 timer_id = root.after(AUTO_HIDE_DELAY, root.withdraw) # 绑定i3焦点切换事件 i3.on("window::focus", update_focus_display) # 初始启动时显示当前聚焦窗口 update_focus_display(None) # 启动事件循环 try: root.mainloop() finally: i3.main_quit()
代码说明
- 窗口样式:我添加了一些样式优化(比如深色背景、无边框),你可以根据自己的桌面主题调整
bg、fg、字体等参数 - 自动隐藏逻辑:用
root.withdraw()隐藏窗口而不是销毁,这样下次显示时不需要重新创建组件,更流畅;如果需要彻底关闭窗口,可以把root.withdraw()换成root.destroy(),但注意这种情况下下次需要重新初始化窗口 - 事件处理:
update_focus_display函数会在每次焦点切换时被调用,它会先取消之前的定时器,确保窗口不会在用户刚切换焦点就消失,然后更新内容并重新设置定时器
内容的提问来源于stack exchange,提问作者TheSupport101
相关产品推荐
相关产品推荐

