Python Tkinter报错:'Buttons1'对象无'destroy'属性,求解决方案
解决Tkinter窗口销毁失败与输入内容无法写入的问题
我来帮你搞定这个问题!你遇到的报错和功能失效主要是两个核心原因:自定义类误用destroy()方法,以及输入内容获取时机错误,咱们一步步修复:
1. 为什么会出现AttributeError: 'Buttons1' object has no attribute 'destroy'?
Buttons1是你自己定义的类,它本身不是Tkinter的窗口组件(比如Toplevel或Tk),所以没有destroy()方法。你要关闭的是Buttons1实例对应的Toplevel窗口,也就是它的self.master属性。
同时你代码里的master.deiconify()也有问题——这里的master没有定义,应该调用主窗口的deiconify(),也就是self.master.master.deiconify()(因为Buttons1的master是AddDrugWindow,而AddDrugWindow的master是主窗口)。
2. 为什么输入内容无法正确写入?
你现在在创建Add_Drug_Window的时候就调用了get()获取输入框内容,这时候用户还没输入任何内容,拿到的是空字符串。应该把获取输入的逻辑移到用户点击OK按钮的时候。另外全局变量可以不用,改用类属性传递数据更符合Python面向对象的规范。
修改后的完整代码
from tkinter import * class Buttons: def __init__(self, master): self.master = master self.frame = Frame(self.master) self.b1 = Button(self.master, text="Add a New Drug", command=self.Add_Drug_Window) self.b1.grid() self.frame.grid() def Add_Drug_Window(self): # self.master.withdraw() # 如果需要隐藏主窗口可以取消注释 self.AddDrugWindow = Toplevel(self.master) # 把当前Buttons实例传给Buttons1,方便它获取输入框内容 self.okbutton = Buttons1(self.AddDrugWindow, self) # 创建输入控件 Label(self.AddDrugWindow, text="Drug name").grid(row=0) Label(self.AddDrugWindow, text="Url :").grid(row=1) self.newdrugnameEntry = Entry(self.AddDrugWindow) self.newurlEntry = Entry(self.AddDrugWindow) self.newdrugnameEntry.grid(row=0, column=1) self.newurlEntry.grid(row=1, column=1) class Buttons1: def __init__(self, master, main_app): self.master = master self.main_app = main_app # 保存主应用实例,用来获取输入框内容 self.frame = Frame(self.master) self.bok = Button(self.master, text="ok", command=self.ok) self.bok.grid(row=3, column=0) self.frame.grid() def ok(self): # 点击OK时才获取输入内容 newdrugname = self.main_app.newdrugnameEntry.get() newurl = self.main_app.newurlEntry.get() # 写入文件 with open('lorem_ipsum.txt', 'a') as f: f.write(f'\n{newdrugname}:{newurl}') # 关闭当前Toplevel窗口 self.master.destroy() # 如果之前隐藏了主窗口,取消下面的注释 # self.main_app.master.deiconify() if __name__ == '__main__': fenetreroot = Tk() b = Buttons(fenetreroot) fenetreroot.mainloop()
关键修改点说明
- 给
Buttons1的构造函数增加了main_app参数,用来传递Buttons类的实例,这样就能直接访问输入框的内容,不需要全局变量 - 将获取输入内容的代码移到
ok()方法里,确保拿到的是用户输入后的有效内容 - 把
self.destroy()改为self.master.destroy(),正确关闭Toplevel窗口 - 修正了
deiconify()的调用对象(如果需要隐藏主窗口的话)
这样修改后,点击OK按钮就能正常关闭添加窗口,并且把输入的药品信息写入TXT文件了!
内容的提问来源于stack exchange,提问作者Arty
相关产品推荐
相关产品推荐

