Tkinter加载Label图片时提示pyimage1不存在但实际存在的问题
问题:Tkinter报错“image 'pyimage1' doesn't exist”
错误日志
[(<memory at 0x000001ADB67D2040>,)] 1 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=592x1052 at 0x1ADB67FF280> =-----------------------------------= pyimage1 Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\Player 1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__ return self.func(*args) File "c:\Users\Player 1\OneDrive\Documents\Year 13\Computer Science\NEA\Code\windows.py", line 373, in <lambda> images_button = tkinter.Button(self, text="View {} Images".format(listingname), font=('calibre', 20, 'bold'), command=lambda: self.create_command_for_Nav_Buttons("Pictures", condition=listing_id)).grid(column=0, row=0, rowspan=7) File "c:\Users\Player 1\OneDrive\Documents\Year 13\Computer Science\NEA\Code\windows.py", line 77, in create_command_for_Nav_Buttons start_window.create_page(condition) File "c:\Users\Player 1\OneDrive\Documents\Year 13\Computer Science\NEA\Code\windows.py", line 412, in create_page images = tkinter.Label(master=self, image=photo, width=300, height=300) File "C:\Users\Player 1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 3148, in __init__ Widget.__init__(self, master, 'label', cnf, kw) File "C:\Users\Player 1\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2572, in __init__ self.tk.call( _tkinter.TclError: image "pyimage1" doesn't exist
问题代码
class picture_page(Window): def __init__(self, current_window="Pictures!") -> None: super().__init__(current_window) def create_page(self, listing_id): imagesMView_list = dbm.getImagesForListing(listing_id) print(imagesMView_list) print(len(imagesMView_list)) if len(imagesMView_list) == 0: self.create_Label("There are no images!", ('calibre', 20, 'bold'), 0, 0) else: processedImage_list = [] for i in range(len(imagesMView_list[0])): processedImage_list.append(bytes(imagesMView_list[0][i])) # for i in range(len(processedImage_list)): # img = Image.open(io.BytesIO(processedImage_list[i])) # photo = ImageTk.PhotoImage(img) # print(img) # print(photo) # tkinter.Label(master=self, image=photo).pack() for i in range(len(processedImage_list)): img = Image.open(io.BytesIO(processedImage_list[i])) print(img) print("=-----------------------------------=") photo = ImageTk.PhotoImage(img) print(photo) images = tkinter.Label(master=self, image=photo, width=300, height=300) images.grid(column=i, row=0)
补充说明
- 已尝试用
global photo保留引用但无效 picture_page继承自Window类,Window类继承自Tk- 图片来自数据库字节数组,转换为JPEG已验证成功
- 试过注释里的
pack()布局方式,同样报错
解决方案
核心原因
Tkinter的PhotoImage对象依赖Python的引用计数维持生命周期,若没有被持久化变量持有引用,Python垃圾回收会自动销毁它,导致Tcl层面找不到对应的图片对象,触发“image doesn't exist”错误。global无效是因为循环内的photo是局部变量,循环结束后就会被回收;另外多Tk实例(picture_page继承自Tk)也可能引发上下文冲突,加重这个问题。
具体修复方案
方案一:绑定PhotoImage到Label实例
创建Label后,将photo赋值给Label的自定义属性,让Label持有图片引用,避免被回收:
for i in range(len(processedImage_list)): img = Image.open(io.BytesIO(processedImage_list[i])) photo = ImageTk.PhotoImage(img) images = tkinter.Label(master=self, image=photo, width=300, height=300) images.photo = photo # 关键:绑定引用到Label images.grid(column=i, row=0)
方案二:用类实例变量保存所有图片引用
在picture_page类中初始化一个列表,专门存储PhotoImage对象,确保实例存活期间引用不会丢失:
class picture_page(Window): def __init__(self, current_window="Pictures!") -> None: super().__init__(current_window) self.photo_references = [] # 新增:存储图片引用 def create_page(self, listing_id): # ... 其他代码不变 ... for i in range(len(processedImage_list)): img = Image.open(io.BytesIO(processedImage_list[i])) photo = ImageTk.PhotoImage(img) self.photo_references.append(photo) # 保存引用 images = tkinter.Label(master=self, image=photo, width=300, height=300) images.grid(column=i, row=0)
方案三:避免多Tk实例(可选)
如果程序已有主Tk窗口,建议将picture_page改为继承Toplevel(而不是继承自Window),多Tk实例会导致Tcl上下文混乱,也可能引发图片找不到的问题:
class picture_page(tkinter.Toplevel): # 修改继承类 def __init__(self, current_window="Pictures!") -> None: super().__init__(title=current_window) # ... 其他代码不变 ...
内容的提问来源于stack exchange,提问作者Hassan Shafeeq
相关产品推荐
相关产品推荐

