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

Python Tkinter打开第二个窗口时关闭第一个窗口的异常问题

问题分析

你的核心问题在于:Tkinter的主窗口(Tk()实例)是所有子窗口的父容器,直接调用quit()会终止整个mainloop导致程序退出,调用destroy()会销毁主窗口并连带关闭所有子窗口,所以才会出现要么双窗口都关、要么新窗口无法打开的情况。

解决方案

我们可以用一个隐藏的主Tk窗口作为后台的事件循环载体,所有实际显示的窗口都用Toplevel实现。每次打开新窗口时销毁当前的可见窗口,这样全程只维持一个mainloop,且不会同时存在多个可见窗口,完美适配你23个树形窗口的需求。

修改后的代码如下:

from tkinter import *
from tkinter import ttk

class BaseWindow(Toplevel):
    """基础窗口类,封装通用初始化逻辑"""
    def __init__(self, parent, title, geometry):
        super().__init__(parent)
        self.parent = parent  # 保存隐藏的主窗口引用
        self.geometry(geometry)
        self.title(title)

class TargetWindow(BaseWindow):
    """第二个窗口(可扩展为后续树形窗口)"""
    def __init__(self, parent):
        super().__init__(parent, 'Toplevel Window', '300x100')
        # 关闭按钮:销毁自身后关闭主窗口,结束程序
        ttk.Button(self, text='Close', command=self.shutdown_app).pack(expand=True)
    
    def shutdown_app(self):
        self.destroy()
        self.parent.destroy()

class InitialWindow(BaseWindow):
    """第一个窗口"""
    def __init__(self, parent):
        super().__init__(parent, 'Main Window', '300x200')
        ttk.Button(self, text='Open a window', command=self.switch_window).pack(expand=True)
    
    def switch_window(self):
        # 创建新窗口
        new_window = TargetWindow(self.parent)
        new_window.grab_set()  # 聚焦新窗口
        # 销毁当前窗口
        self.destroy()

if __name__ == "__main__":
    # 创建主窗口并隐藏,作为后台事件循环
    root = Tk()
    root.withdraw()
    # 启动第一个可见窗口
    InitialWindow(root)
    root.mainloop()
关键说明
  • root.withdraw():隐藏主Tk窗口,它只负责维持mainloop,不参与界面显示
  • 所有业务窗口继承Toplevel,以隐藏的主窗口作为父容器
  • 切换窗口时,先创建新窗口,再销毁当前窗口,确保mainloop持续运行
  • 最后一个窗口关闭时,调用self.parent.destroy()销毁主窗口,彻底结束程序

内容的提问来源于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.23 16:27:21