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

为何调用tk.Toplevel会生成两个窗口?

Tkinter 子窗体弹出双窗口问题解决

问题现象

主程序(frmMain)调用createForm打开子窗体时,每次会弹出两个窗口:一个是正常的目标子窗体,另一个是空白且无法通过右上角关闭按钮关闭的异常窗口。

错误代码示例

frmMain=tk.Tk()

def createForm():
    lFrm = tk.Toplevel()    # 创建新窗体
    initForm(lFrm)          # 初始化窗体并设置焦点事件冒泡
    return lFrm
    
def initForm(pFrm):
    tk.Toplevel.__init__(pFrm) # 手动调用父类初始化(未使用super)
    # super().__init__(master=pFrm)
    setWindowFocusEvent(pFrm) # 实现MDI应用的焦点联动:任意窗口获焦时,所有窗口按顺序前置

调用示例:

def listBands():
    global frmMain
    frmMain.lListBandsFrm = createForm()

排查过程

  • 确认代码中没有重复调用tk.Tk(),每个窗体仅调用一次tk.Toplevel()
  • 尝试移除tk.Toplevel.__init__(pFrm)调用,会导致功能异常(如无法使用.bind方法绑定事件)

问题根源

错误代码中,initForm函数接收的pFrm已经是tk.Toplevel的实例,此时再次调用tk.Toplevel.__init__(pFrm)相当于重复初始化Toplevel对象,额外创建了一个空白窗口。

正确解决方案:子类化Tk.Toplevel

通过子类化tk.Toplevel,在子类的__init__方法中正确调用父类初始化逻辑,避免重复创建窗口的同时保留所需功能:

class FrmMDI(tk.Toplevel):  # 自定义MDI子窗体类,包含所需初始化逻辑
    def __init__(self):     # 实例化时自动调用
        super().__init__()  # 正确调用父类Toplevel的初始化方法
        setWindowFocusEvent(self) # 设置MDI焦点联动逻辑,优化Windows下的多窗口体验

def createForm():      
    lFrm = FrmMDI()    # 使用自定义子类创建子窗体
    return lFrm

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:44:54