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

如何全局引用函数内创建的对象?tkinter中NameError问题解决

问题分析与解决

错误原因

你遇到的NameError: newWindow not defined是因为程序启动后立刻执行了if not newWindow.winfo_exists(),但此时newWindow变量还未创建——它只有在右键点击按钮触发darkmode函数、进而调用createWindow后才会被初始化,这直接导致了变量未定义的报错。同时,主循环启动前的if判断只会执行一次,无法实时监听Toplevel窗口的关闭状态,逻辑本身不成立。

修正方案

正确的做法是给Toplevel窗口绑定关闭事件,当用户关闭该窗口时自动触发主窗口重新显示的操作,同时移除主循环前无效的判断代码。

修正后的代码

from tkinter import *

def answer(event):
    AnsLabel["text"] = "You clicked the Button!"

def darkmode(event):
    # 切换暗黑模式样式
    Hallo["fg"] = "white"
    Hallo["bg"] = "black"
    main["bg"] = "black"
    AnsLabel["bg"] = "black"
    AnsLabel["fg"] = "white"
    button["bg"] = "black"
    button["fg"] = "white"
    # 3秒后执行创建新窗口并隐藏主窗口的操作
    main.after(3000, createWindow)

def show_main_window():
    # 重新显示主窗口
    main.deiconify()

def createWindow():
    newWindow = Toplevel()
    newLabel = Label(newWindow, text="You found the secret function!")
    newLabel.pack()
    # 绑定Toplevel窗口的关闭事件:销毁窗口后显示主窗口
    newWindow.protocol("WM_DELETE_WINDOW", lambda: (newWindow.destroy(), show_main_window()))
    # 隐藏主窗口
    main.withdraw()

main = Tk()
Hallo = Label(main, text="Hello")
button = Button(main, text="BUTTON")
button.bind("<Button-1>", answer)
button.bind("<Button-3>", darkmode)
AnsLabel = Label(main, text="Hello!")

Hallo.pack()
button.pack()
AnsLabel.pack()

main.mainloop()

关键修改点

  • 移除了主循环前的if not newWindow.winfo_exists()判断,彻底避免启动时的变量未定义错误。
  • 新增show_main_window函数,专门负责重新显示主窗口,逻辑更清晰。
  • 在createWindow中使用newWindow.protocol("WM_DELETE_WINDOW", ...)绑定窗口关闭事件,确保用户关闭Toplevel窗口时,自动触发主窗口的显示操作。
  • 不再需要global newWindow,通过事件绑定的方式直接处理窗口状态变化,无需依赖全局变量传递状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:10:29