You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CustomTkinter加载背景图片时报错_tkinter.TclError: image 'pyimage2' doesn't exist 求助

CustomTkinter加载背景图片时报错_tkinter.TclError: image 'pyimage2' doesn't exist 求助

Hey there! 先别慌,这个错误我之前踩过坑,大概率是你在while True循环里反复创建新的CustomTkinter窗口实例导致的——Tkinter(CustomTkinter的底层依赖)不允许同时存在多个主Tk窗口实例,重复创建会打乱Tcl解释器的资源管理逻辑,图片对象的引用就会出现混乱,进而抛出pyimageX找不到的错误。

问题根源拆解

你当前的逻辑是:每次检测不到目标截图,就新建一个tela2 = ctk.CTk()窗口,但之前创建的窗口并没有被销毁,多个Tk实例共存会让图片资源的上下文彻底乱掉,这就是报错的核心原因。

解决方案推荐

我给你两种可行的修改思路,你可以根据自己的需求选:

方案1:只初始化一次窗口,循环控制显示/隐藏

把窗口和图片的初始化代码移到循环外面,循环里只负责判断是否显示/隐藏窗口,彻底避免多Tk实例冲突:

import customtkinter as ctk
from PIL import Image
import pyautogui as py
import time
import os

# 先获取正确的脚本目录,避免路径出错
here = os.path.abspath(os.path.dirname(__file__))

# 初始化窗口(只做一次)
tela2 = ctk.CTk()
tela2.title("Desktop - Login Easyware")
tela2.geometry("1280x720")
tela2.resizable(False, False)
tela2.configure(fg_color="#FAFAFA")
ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("dark-blue")
tela2.iconbitmap(fr"{here}\imagens\desktop.ico")

# 只加载一次图片,复用资源
img2 = ctk.CTkImage(
    light_image=Image.open(fr"{here}\imagens\login.png"),
    dark_image=Image.open(fr"{here}\imagens\login.png"),
    size=(1280, 720)
)
background = ctk.CTkLabel(tela2, text=None, image=img2)
background.place(x=0, y=0)

# 用Tk的after方法做循环检测,避免阻塞主事件循环
def check_login_status():
    if not py.locateOnScreen(fr"{here}\\imagens\\erro_login_easy.png", confidence=0.8):
        # 显示窗口
        tela2.deiconify()
    else:
        # 隐藏窗口
        tela2.withdraw()
    # 每隔1秒重复检测一次
    tela2.after(1000, check_login_status)

# 启动检测逻辑
check_login_status()
tela2.mainloop()

方案2:如果必须新建窗口,先销毁旧实例

如果你的业务逻辑确实需要每次新建窗口,那一定要确保创建新窗口前销毁旧窗口:

import customtkinter as ctk
from PIL import Image
import pyautogui as py
import time
import os

here = os.path.abspath(os.path.dirname(__file__))
tela2 = None
img2 = None  # 复用图片,避免重复加载

while True:
    if not py.locateOnScreen(fr"{here}\\imagens\\erro_login_easy.png", confidence=0.8):
        # 销毁旧窗口(如果存在)
        if tela2 is not None:
            tela2.destroy()
        
        # 新建窗口
        tela2 = ctk.CTk()
        tela2.title("Desktop - Login Easyware")
        tela2.geometry("1280x720")
        tela2.resizable(False, False)
        tela2.configure(fg_color="#FAFAFA")
        ctk.set_appearance_mode("dark")
        ctk.set_default_color_theme("dark-blue")
        tela2.iconbitmap(fr"{here}\imagens\desktop.ico")

        # 只加载一次图片
        if img2 is None:
            img2 = ctk.CTkImage(
                light_image=Image.open(fr"{here}\imagens\login.png"),
                dark_image=Image.open(fr"{here}\imagens\login.png"),
                size=(1280, 720)
            )
        
        background = ctk.CTkLabel(tela2, text=None, image=img2)
        background.place(x=0, y=0)
        
        tela2.mainloop()
    else:
        # 登录成功后销毁窗口
        if tela2 is not None:
            tela2.destroy()
            tela2 = None
        time.sleep(1)

额外小提示

记得确认你的图片路径是否正确,用os.path.abspath获取绝对路径能有效避免相对路径的坑;另外,py.locateOnScreen的检测频率别太高,加个time.sleep能减少资源占用哦。

备注:内容来源于stack exchange,提问作者Kdufsz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 13:00:28