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

如何让Tkinter的Toplevel窗口不触发父组件的FocusOut事件

解决方案:过滤应用内窗口切换的FocusOut事件

可以实现需求。问题核心在于:即便将Toplevel的master设为Frame,它仍是独立的顶层窗口,当焦点在同一应用的不同顶层窗口间切换时,原Frame的FocusOut事件仍会被触发。解决思路是在事件处理函数中判断新焦点是否属于当前应用的窗口,若是则跳过事件执行。

修改后的代码如下:

from tkinter import Tk, Frame, Entry, Toplevel


def focus_out(event):
    # 通过点击位置反查新焦点所在的组件
    new_focus_widget = event.widget.winfo_containing(event.x_root, event.y_root)
    if new_focus_widget:
        # 获取该组件所属的顶层窗口
        target_toplevel = new_focus_widget.winfo_toplevel()
        # 检查顶层窗口是否属于当前应用的窗口
        if target_toplevel in (root, t):
            return
    # 仅当焦点离开当前应用时执行操作
    print("focus out")


root = Tk()
root.title("Main")
root.geometry("400x400")

frame = Frame(root)
frame.pack()
frame.bind("<FocusOut>", focus_out)

e = Entry(frame)
e.pack()

t = Toplevel(frame)
t.geometry("400x400")
t.title("top level")
Entry(t).pack()

root.mainloop()

关键逻辑说明

  • winfo_containing(event.x_root, event.y_root):利用鼠标点击的屏幕坐标,定位新获得焦点的组件。
  • winfo_toplevel():获取组件所属的顶层窗口(Tk或Toplevel实例)。
  • 若目标顶层窗口是当前应用内的窗口(root或自定义的Toplevel),则直接返回,不执行后续事件逻辑。

调整后,从主窗口Entry切换到Toplevel窗口的Entry时,不会触发Frame的FocusOut事件;只有当焦点切换到其他应用窗口时,才会执行事件代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:07:38