Python Tkinter窗口关闭失败:NameError问题原因及修复
错误原因分析
- 你在
ButtonFrame类的__create_widgets方法里直接引用了app.exit,但app是仅在if __name__ == "__main__"代码块中定义的局部变量,ButtonFrame类的作用域无法访问到这个变量,因此触发NameError。 - 额外问题:你将
grid()方法的返回值赋值给了self.button,但grid()方法返回None,后续如果要对按钮控件进行操作会失效。
修复方案
提供两种可靠的修复方式:
方式一:通过传入的容器实例调用exit方法
ButtonFrame初始化时接收的container就是App类的实例,直接通过它绑定命令即可,同时修正按钮赋值问题:
class ButtonFrame(ttk.Frame): def __init__(self, container): super().__init__(container) self.container = container # 保存容器实例引用 self.__create_widgets() def __create_widgets(self): # 先创建按钮对象,再调用grid布局,避免把None赋值给self.button self.button = ttk.Button(self, text=' EXIT', command=self.container.exit) self.button.grid(column=0, row=0, sticky='ew') self.grid(padx=0, pady=0)
方式二:直接绑定顶层窗口的destroy方法
如果仅需要实现关闭窗口的功能,也可以跳过App类的exit方法,直接调用顶层窗口的destroy方法:
def __create_widgets(self): self.button = ttk.Button(self, text=' EXIT', command=self.winfo_toplevel().destroy) self.button.grid(column=0, row=0, sticky='ew') self.grid(padx=0, pady=0)
完整修复后的代码
#!/usr/bin/python3.9 import tkinter as tk from tkinter import ttk class ButtonFrame(ttk.Frame): def __init__(self, container): super().__init__(container) self.container = container self.__create_widgets() def __create_widgets(self): self.button = ttk.Button(self, text=' EXIT', command=self.container.exit) self.button.grid(column=0, row=0, sticky='ew') self.grid(padx=0, pady=0) class App(tk.Tk): def __init__(self): super().__init__() self.configure(bg='#ff3800') self.geometry("500x200") # wxh self.resizable(False, False) # layout on the root window self.columnconfigure(0, weight=1) self.__create_widgets() def __create_widgets(self): # create the button frame button_frame = ButtonFrame(self) button_frame.grid(column=0, row=0) def exit(self): self.destroy() if __name__ == "__main__": app = App() app.mainloop()
内容的提问来源于stack exchange,提问作者bob_the_bob
相关产品推荐
相关产品推荐

