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

为何这段简单的Tkinter代码会创建两个顶级窗口?

为什么你的Tkinter代码会弹出两个顶级窗口?

核心原因很简单:每调用一次tk.Tk()就会创建一个独立的Tkinter主应用实例,对应一个顶级窗口。不管这个实例有没有被变量保存,Tkinter底层都会保留对主窗口实例的引用,不会被立即垃圾回收,所以窗口会一直显示。

看你的第一段代码:

import tkinter as tk

class GUI:
    def __init__(self):
        self.top_level_window = tk.Tk()
        

GUI()  # 实例化时调用tk.Tk(),生成第一个窗口
GUI().top_level_window.mainloop()  # 再次实例化,又调用一次tk.Tk()生成第二个窗口,随后启动主循环

两次GUI()实例化等于两次tk.Tk()调用,自然会生成两个独立的顶级窗口。哪怕第一个GUI实例没有被变量引用,它对应的Tk主窗口实例也不会被销毁。

再看修改后的代码:

a=GUI()  # 第一次调用tk.Tk(),生成第一个窗口
b=GUI()  # 第二次调用tk.Tk(),生成第二个窗口
b.top_level_window.mainloop()  # 启动主循环时,两个Tk实例都存在,所以两个窗口都显示

本质还是两次tk.Tk()调用,结果当然还是两个窗口。

正确的写法

Tkinter应用应该遵循「一个主Tk实例 + 多个Toplevel子窗口」的模式,确保只调用一次tk.Tk():

import tkinter as tk

class GUI:
    def __init__(self, root):
        # 使用传入的主Tk实例,避免重复创建
        self.window = root

# 只创建一次主Tk实例
main_root = tk.Tk()
main_gui = GUI(main_root)

# 如果需要新窗口,用Toplevel(基于主Tk实例)
sub_window = tk.Toplevel(main_root)

# 启动主循环(只需启动主Tk实例的循环即可)
main_root.mainloop()

或者如果你的类需要区分主窗口和子窗口,可以这样写:

import tkinter as tk

class GUI:
    def __init__(self, is_main=False):
        if is_main:
            self.window = tk.Tk()
        else:
            # 确保已有主Tk实例,没有则自动创建
            if not tk._default_root:
                tk.Tk()
            self.window = tk.Toplevel()

# 创建主窗口
main_gui = GUI(is_main=True)
# 创建子窗口
sub_gui = GUI()

main_gui.window.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:10:24