为何这段简单的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
相关产品推荐
相关产品推荐

