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

Tkinter中通过代码关闭窗口报错NameError,如何解决?

解决Tkinter点击按钮切换窗口时的NameError问题

这个问题的核心是变量作用域的问题——你在main()函数里定义的top是局部变量,secondary()函数根本访问不到它,所以才会抛出NameError: name 'top' is not defined的错误。下面给你两种可行的修复方案:

方案1:使用全局变量(简单直接)

通过把top声明为全局变量,让secondary()函数能访问到这个窗口实例:

from tkinter import *
import tkinter.messagebox
import os.path

# 先在全局作用域声明top变量
top = None

def main():
    global top  # 告诉函数使用全局的top变量,而非创建局部变量
    # 打开第一个窗口
    top = Tk()
    # 设置窗口样式
    top.configure(bg="#AED6F1")
    top.geometry("800x600+300+80")
    top.title("初始窗口")  # 给窗口补个标题,原代码这里是空的
    
    # 创建按钮并绑定回调函数
    Button_1 = Button(
        top,
        text="Ice",
        bg="#AED6F1",
        relief=FLAT,
        bd=0,
        font="Times 100 bold",
        command=secondary
    )
    Button_1.place(x=0,y=0)
    top.mainloop()

def secondary():
    global top
    top.destroy()  # 现在能正常访问全局的top变量了
    main()  # 重新打开初始窗口

if __name__ == "__main__":
    main()

方案2:传递窗口实例作为参数(更优雅,推荐)

全局变量虽然简单,但长期维护时可能会带来隐患。更好的方式是通过lambda把窗口实例直接传给secondary()函数:

from tkinter import *
import tkinter.messagebox
import os.path

def main():
    # 打开第一个窗口
    top = Tk()
    # 设置窗口样式
    top.configure(bg="#AED6F1")
    top.geometry("800x600+300+80")
    top.title("初始窗口")
    
    # 使用lambda把当前窗口实例传给secondary函数
    Button_1 = Button(
        top,
        text="Ice",
        bg="#AED6F1",
        relief=FLAT,
        bd=0,
        font="Times 100 bold",
        command=lambda: secondary(top)
    )
    Button_1.place(x=0,y=0)
    top.mainloop()

def secondary(window):
    window.destroy()  # 直接操作传入的窗口实例
    main()

if __name__ == "__main__":
    main()

另外补个小细节:原代码里的top.title()没有传入标题文本,我给加上了"初始窗口",你可以根据需求修改成自己想要的标题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:55:18