Tkinter多窗口图片报错:_tkinter.TclError: image "pyimage5" doesn't exist 问题求助
解决Tkinter子窗口中PhotoImage报错
_tkinter.TclError: image "pyimageX" doesn't exist的问题 这个问题我之前做Tkinter项目时也踩过坑,本质是Tkinter的PhotoImage对象和窗口实例的绑定关系以及生命周期管理问题,咱们来一步步解决:
核心原因拆解
你是在第二个窗口创建后才定义的add_icon这些PhotoImage,默认情况下这些图片会绑定到主窗口的Tk实例上,但你的按钮是在子窗口(应该是Toplevel实例)中创建的。Tkinter的图片资源是和对应的Tk上下文绑定的,子窗口无法直接识别主窗口上下文里的图片标识(也就是报错里的pyimage5),所以就会出现找不到图片的错误。另外还要警惕图片对象被垃圾回收的情况——如果图片是局部变量,函数执行完后引用被销毁,Tkinter也会丢失图片资源。
具体解决方法
方法一:给PhotoImage指定master参数关联子窗口
定义图片时,明确把它绑定到你的第二个窗口(也就是代码里的edit窗口),这样图片资源就和子窗口的上下文绑定,按钮就能正常找到它:
# 假设edit是你的子窗口(Toplevel实例) add_icon = PhotoImage(file='data/add_icon.gif', master=edit) subtract_icon = PhotoImage(file='data/subtract_icon.gif', master=edit) # 之后正常创建按钮即可 Button(edit, image=add_icon, command=add_new_pref, relief=FLAT).grid(row=2, column=0, sticky=NSEW) Button(edit, image=subtract_icon, command=remove_pref, relief=FLAT).grid(row=3, column=0, sticky=NSEW)
方法二:确保图片对象不被垃圾回收
如果你的图片是在某个函数内部定义的局部变量,函数执行完毕后变量会被Python的垃圾回收机制销毁,Tkinter也就失去了图片的引用。解决办法是把图片对象挂载到窗口实例上,或者定义为全局变量:
# 把图片挂在子窗口对象上,延长其生命周期 edit.add_icon = PhotoImage(file='data/add_icon.gif', master=edit) edit.subtract_icon = PhotoImage(file='data/subtract_icon.gif', master=edit) # 创建按钮时引用窗口上的图片对象 Button(edit, image=edit.add_icon, command=add_new_pref, relief=FLAT).grid(row=2, column=0, sticky=NSEW) Button(edit, image=edit.subtract_icon, command=remove_pref, relief=FLAT).grid(row=3, column=0, sticky=NSEW)
额外避坑提醒
千万别为第二个窗口新建Tk()实例!如果你创建子窗口时用的是Tk()而不是Toplevel(),那会生成两个完全独立的Tk上下文,图片在一个上下文里定义,另一个上下文肯定找不到。子窗口必须用Toplevel()来创建,这样才能和主窗口共享Tk上下文(或者按方法一绑定到子Toplevel)。
内容的提问来源于stack exchange,提问作者SlavaCat
相关产品推荐
相关产品推荐

