Python/Tkinter开发:如何解决Toplevel对象无filenameA属性的AttributeError报错
问题根因
- 报错
'Toplevel' object has no attribute 'filenameA'的直接原因:你调用filedialog.askopenfilename拿到的路径存在了局部变量filenameA里,没有绑定到neuebox这个Toplevel实例上,直接访问neuebox.filenameA自然找不到这个属性。 - Tkinter的Toplevel本质是普通Python对象,支持动态绑定自定义属性,你需要先执行
neuebox.属性名 = 对应值完成绑定,之后才能在其他作用域读取这个属性。 - 除了这个报错外,你的代码还存在图片垃圾回收不显示、Label参数写错、函数重名覆盖、多mainloop冲突等隐性问题,都需要同步修复。
修复步骤
1. 修复图片选择逻辑(以select_imageA为例,B/C/D按相同逻辑修改)
def select_imageA(): filetypes = [("Bilder als JPEG", "*.jpg")] # 拿到文件路径后直接绑定到neuebox实例,后续才能正常读取 neuebox.filenameA = filedialog.askopenfilename(title='Open a file', initialdir='C:/Benutzer_Marcel_privat/___PROJEKTE_LOKAL_SAVE/PYTHON/KLEINTEILEREGISTER/gui/Images', filetypes=filetypes) # 兼容用户取消选择的场景,避免后续打开空路径报错 if not neuebox.filenameA: return # 打开图片并调整大小适配显示区域 img = Image.open(neuebox.filenameA).resize((420,236)) my_image_A = ImageTk.PhotoImage(img) # 修正参数:Label父组件指定为neuebox,图片参数名是小写的image不是Image Blid_A_Label = Label(neuebox, image=my_image_A) # 必须把图片对象绑定到组件上,避免Python垃圾回收导致图片不显示 Blid_A_Label.image = my_image_A Blid_A_Label.place(x=80, y=550, width=420, height=236)
2. 修复重复定义的转换函数
你现在写了4个同名的convertToBinaryData,后面的定义会覆盖前面的,直接删掉重复的,留一个通用函数即可:
# 全局保留一个通用二进制转换函数,所有图片都可以复用 def convertToBinaryData(filename): with open(filename, 'rb') as file: return file.read()
3. 修复submit函数的图片入库逻辑
把注释掉的图片字段参数补全,兼容未上传图片的场景:
def submit(): conn = sqlite3.connect("KTR.db") c = conn.cursor() # 先判断对应图片是否已上传,未上传则存空值 bild_a = convertToBinaryData(neuebox.filenameA) if hasattr(neuebox, 'filenameA') else None bild_b = convertToBinaryData(neuebox.filenameB) if hasattr(neuebox, 'filenameB') else None bild_c = convertToBinaryData(neuebox.filenameC) if hasattr(neuebox, 'filenameC') else None bild_d = convertToBinaryData(neuebox.filenameD) if hasattr(neuebox, 'filenameD') else None c.execute("INSERT INTO KTR_table VALUES(:lagerortEntry, :fachEntry, :boxnoEntry, :kategorie1eingabeVariable, :kategorie2eingabeVariable, :inhaltText, :BildA_label, :BildB_label, :BildC_label, :BildD_label)", { "lagerortEntry": lagerortEntry.get(), "fachEntry": fachEntry.get(), "boxnoEntry": boxnoEntry.get(), "kategorie1eingabeVariable": kategorie1eingabeVariable.get(), "kategorie2eingabeVariable": kategorie2eingabeVariable.get(), "inhaltText": inhaltText.get("1.0",END), "BildA_label": bild_a, "BildB_label": bild_b, "BildC_label": bild_c, "BildD_label": bild_d }) # 后面原有清空输入、提交关闭连接的逻辑保持不变
4. 其他隐性问题修复
- Toplevel窗口不需要单独运行mainloop,主窗口已经有全局mainloop,删掉代码最后一行
neuebox.mainloop()避免窗口冲突 - 所有select_imageB/C/D都按照select_imageA的逻辑修改,把filename绑定到neuebox实例,同时处理图片垃圾回收问题
内容的提问来源于stack exchange,提问作者Kinderdisco Goodtime
相关产品推荐
相关产品推荐

