Tkinter向ScrolledText控件添加BMP图片时报错图片不存在怎么解决?
错误原因
该报错是Tkinter的经典引用丢失问题:你在调用image_create方法时,直接将ImageTk.PhotoImage(img)作为临时参数传入,没有为生成的PhotoImage对象保留持久引用。Python的垃圾回收机制会在该行代码执行完成后,销毁没有被任何变量持有的PhotoImage临时对象,Tkinter内核后续渲染时找不到对应的图片内存资源,就会抛出图片不存在的错误。
修复方案
- 核心修复:为PhotoImage对象绑定一个生命周期足够长的引用,最简单的实现是将其作为属性绑定到ScrolledText控件对象上,只要控件不被销毁,图片引用就不会被垃圾回收机制清理。
- 可选优化:无需将提取的图标保存为本地BMP文件再读取,可直接从内存转换为PIL对象,减少不必要的IO操作;同时建议补充Win32资源释放逻辑,避免长期运行产生GDI句柄泄漏。
修正后核心代码示例
def get_icon(exe): ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON) ico_y = win32api.GetSystemMetrics(win32con.SM_CYICON) large, small = win32gui.ExtractIconEx(exe, 0) win32gui.DestroyIcon(small[0]) hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_y) mem_hdc = hdc.CreateCompatibleDC() mem_hdc.SelectObject(hbmp) mem_hdc.DrawIcon((0, 0), large[0]) # 直接从内存转PIL对象,无需写本地文件 bmp_info = hbmp.GetInfo() bmp_str = hbmp.GetBitmapBits(True) img = Image.frombuffer( 'RGB', (bmp_info['bmWidth'], bmp_info['bmHeight']), bmp_str, 'raw', 'BGRX', 0, 1 ) # 释放Win32资源,避免句柄泄漏 win32gui.DestroyIcon(large[0]) mem_hdc.DeleteDC() hdc.DeleteDC() win32gui.DeleteObject(hbmp.GetHandle()) return img text_area = ScrolledText(root, width = 40, height = 40, font = ("Times New Roman", 25)) # 路径前加r避免转义字符异常 img = get_icon(r"C:\Program Files\BraveSoftware\Brave-Browser\Application\Brave.exe") # 保存PhotoImage的持久引用 tk_img = ImageTk.PhotoImage(img) # 绑定到控件属性,防止被垃圾回收 text_area.icon_cache = tk_img text_area.image_create("current", padx=5, pady=5, image=tk_img) text_area.place(relx=0.2, rely=0.1, relwidth=0.5, relheight=0.5, anchor='s')
内容的提问来源于stack exchange,提问作者Tippitytopkek
相关产品推荐
相关产品推荐

