Tkinter报错‘pyimage2 doesn't exist’问题求助
Tkinter报错
_tkinter.TclError: image "pyimage2" doesn't exist 解决指南 问题背景
开发小型Tkinter项目时,出现_tkinter.TclError: image "pyimage2" doesn't exist错误,同时存在两个窗口中一个缺失图片、自定义图标未生效的问题,需要跨平台解决方案(目标系统为Windows)。
完整报错信息
Traceback (most recent call last): File "D:\red zone\main.py", line 5, in <module> b = updateError((500,500)) File "D:\red zone\scripts\windows.py", line 44, in __init__ self.widget["image"] = self.widget.errorImage File "C:\Users\maude_u0wvgig\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 1727, in __setitem__ self.configure({key: value}) File "C:\Users\maude_u0wvgig\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 1716, in configure return self._configure('configure', cnf, kw) File "C:\Users\maude_u0wvgig\AppData\Local\Programs\Python\Python312\Lib\tkinter\__init__.py", line 1706, in _configure self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) _tkinter.TclError: image "pyimage2" doesn't exist
项目目录结构
\assets err.png \scripts windows.py main.py
原代码文件
windows.py
## imports import base64 import os import tempfile import time import tkinter as tk import zlib from tkinter import * from tkinter import ttk class updateError(): def __init__(self, isTk=False, pos=[500,500]): ## variables self.ICON = zlib.decompress(base64.b64decode('eJxjYGAEQgEBBiDJwZDBy' 'sAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4JRMApGwQgF/ykEAFXxQRc=')) ## main program # window setup self._, self.ICON_PATH = tempfile.mkstemp() with open(self.ICON_PATH, 'wb') as self.icon_file: self.icon_file.write(self.ICON) if isTk: self.root = Tk() elif not isTk: self.root = Toplevel() elif type(isTk) is not bool: raise TypeError(f"needs bool, not {type(isTk)}") if not 0 <= pos[0] <= 900: raise ValueError("x position must be between 0 and 900") elif not 0 <= pos[1] <= 750: raise ValueError("y position must be between 0 and 750") self.frm = ttk.Frame(self.root, padding=10) self.frm.grid() # window content ttk.Label(self.frm, text="Windows was not installed properly. Please reinstall Windows.\nError 4 (Windows error 096)").grid(column=1, row=0) ttk.Button(self.frm, text="Ok").grid(column=5, row=3) # window config self.root.geometry(f"+{pos[0]}+{pos[1]}") self.root.title("Microsoft Windows") self.root.resizable(width=False, height=False) self.root.iconbitmap(default=self.ICON_PATH) self.widget = ttk.Label(self.frm) self.widget.errorImage = tk.PhotoImage(file=r"assets\err.png") self.widget["image"] = self.widget.errorImage self.widget.grid(column=0, row=0) self.root.after(1, lambda: self.root.focus_force())
main.py
## imports from scripts.windows import updateError a = updateError(True, (900,750)) b = updateError((500,500))
问题原因
pyimage2错误:PhotoImage默认与创建它时的主Tk实例绑定。第二个窗口是Toplevel,创建图片时未指定所属窗口,图片会绑定到第一个Tk实例,导致第二个窗口组件无法找到该图片资源。- 图标不生效:
iconbitmap(default=...)仅对主窗口生效,Toplevel需单独设置;且iconbitmap跨平台兼容性差,非Windows系统支持有限。 - 路径隐患:相对路径加载图片时,若程序运行目录不是项目根目录,会导致图片找不到。
- 缺少事件循环:原代码未调用
mainloop(),窗口无法正常稳定显示。
修复方案
1. 为PhotoImage指定所属窗口
创建图片时,通过master参数绑定到当前窗口实例,确保上下文匹配:
self.widget.errorImage = tk.PhotoImage(file=图片路径, master=self.root)
2. 跨平台设置窗口图标
替换iconbitmap为iconphoto,直接加载base64解码后的图标数据,无需临时文件,且跨平台兼容:
self.icon_img = tk.PhotoImage(data=self.ICON) self.root.iconphoto(True, self.icon_img)
需保存图标引用,避免被Python垃圾回收机制回收。
3. 使用绝对路径加载图片
避免相对路径的不确定性,通过脚本目录拼接图片绝对路径:
script_dir = os.path.dirname(os.path.abspath(__file__)) image_path = os.path.join(script_dir, "../assets/err.png")
4. 添加主事件循环
在main.py末尾添加tk.mainloop(),启动Tkinter事件循环,确保窗口正常显示。
修复后的完整代码
windows.py
## imports import base64 import os import tkinter as tk import zlib from tkinter import ttk class updateError(): def __init__(self, isTk=False, pos=[500,500]): ## variables self.ICON = zlib.decompress(base64.b64decode('eJxjYGAEQgEBBiDJwZDBy' 'sAgxsDAoAHEQCEGBQaIOAg4sDIgACMUj4JRMApGwQgF/ykEAFXxQRc=')) ## main program # window setup if isTk: self.root = tk.Tk() elif not isTk: self.root = tk.Toplevel() else: raise TypeError(f"needs bool, not {type(isTk)}") if not 0 <= pos[0] <= 900: raise ValueError("x position must be between 0 and 900") elif not 0 <= pos[1] <= 750: raise ValueError("y position must be between 0 and 750") self.frm = ttk.Frame(self.root, padding=10) self.frm.grid() # 跨平台设置图标 self.icon_img = tk.PhotoImage(data=self.ICON) self.root.iconphoto(True, self.icon_img) # window content ttk.Label(self.frm, text="Windows was not installed properly. Please reinstall Windows.\nError 4 (Windows error 096)").grid(column=1, row=0) ttk.Button(self.frm, text="Ok").grid(column=5, row=3) # window config self.root.geometry(f"+{pos[0]}+{pos[1]}") self.root.title("Microsoft Windows") self.root.resizable(width=False, height=False) # 加载图片(绝对路径+指定master) script_dir = os.path.dirname(os.path.abspath(__file__)) image_path = os.path.join(script_dir, "../assets/err.png") self.widget = ttk.Label(self.frm) self.widget.errorImage = tk.PhotoImage(file=image_path, master=self.root) self.widget["image"] = self.widget.errorImage self.widget.grid(column=0, row=0) self.root.after(1, lambda: self.root.focus_force())
main.py
## imports from scripts.windows import updateError import tkinter as tk a = updateError(True, (900,750)) b = updateError((500,500)) # 启动主事件循环 tk.mainloop()
内容的提问来源于stack exchange,提问作者user23157806
相关产品推荐
相关产品推荐

