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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:04:47