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

Tkinter打开第二个窗口时关闭主窗口失败问题求助

解决Tkinter主窗口与新窗口互斥关闭问题

问题根源

你的代码里Window是Toplevel组件,它以主窗口(App实例)作为父窗口。Tkinter的规则是:当父窗口被销毁时,所有关联的子窗口会被自动关闭。所以你调用self.destroy()销毁主窗口时,刚创建的Toplevel窗口也会被连带销毁,导致要么两个窗口都关闭,要么新窗口无法正常显示。

解决方案

方法1:把新窗口改成独立的Tk实例

让Window直接继承Tk,成为独立的应用窗口,不再依赖原主窗口。打开新窗口时先隐藏主窗口,等新窗口关闭后再销毁主窗口。

修改后的代码:

import tkinter as tk
from tkinter import ttk


class Window(tk.Tk):
    def __init__(self):
        super().__init__()

        self.geometry('300x100')
        self.title('独立窗口')

        ttk.Button(self,
                text='关闭',
                command=self.destroy).pack(expand=True)


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.geometry('300x200')
        self.title('主窗口')

        ttk.Button(self,
                text='打开窗口',
                command=self.open_window).pack(expand=True)

    def open_window(self):
        # 隐藏主窗口
        self.withdraw()
        # 创建独立新窗口
        window = Window()
        # 等待新窗口关闭后,销毁主窗口
        window.wait_window()
        self.destroy()


if __name__ == "__main__":
    app = App()
    app.mainloop()

方法2:隐藏主窗口,新窗口关闭后再销毁主窗口

如果想保留Toplevel的父子关系,不要直接销毁主窗口,而是用withdraw()隐藏它。同时给新窗口绑定关闭事件,等新窗口关闭时再销毁主窗口。

修改后的代码:

import tkinter as tk
from tkinter import ttk


class Window(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)

        self.geometry('300x100')
        self.title('子窗口')
        # 绑定窗口关闭事件,触发父窗口销毁
        self.protocol("WM_DELETE_WINDOW", self.on_close)

        ttk.Button(self,
                text='关闭',
                command=self.destroy).pack(expand=True)

    def on_close(self):
        # 先销毁自身,再销毁主窗口
        self.destroy()
        self.master.destroy()


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.geometry('300x200')
        self.title('主窗口')

        ttk.Button(self,
                text='打开窗口',
                command=self.open_window).pack(expand=True)

    def open_window(self):
        window = Window(self)
        window.grab_set()
        # 隐藏主窗口,而非直接销毁
        self.withdraw()


if __name__ == "__main__":
    app = App()
    app.mainloop()

两种方法的适用场景

  • 方法1适合需要完全独立的窗口场景,新窗口和主窗口是两个独立的Tk实例,互不干扰。
  • 方法2适合需要保持窗口父子关联的场景,通过隐藏主窗口避免子窗口被连带关闭,等子窗口结束后再清理主窗口资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 02:13:16