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

Tkinter多窗口显示选中图片报错:_tkinter.TclError

问题分析与解决方案

错误根源

报错_tkinter.TclError: image "portrait_5" doesn't exist的核心原因:

  • 配置阶段保存的是自定义字符串(如portrait_5),这些字符串既不是Tkinter注册的图像对象名称,也未与实际图片文件建立对应关系。
  • 在lancer函数中直接将配置文件里的字符串传给Label的image参数,Tkinter无法识别该字符串对应的图像资源。
  • 该问题与计时功能的after函数无关,完全是图像资源的加载与引用逻辑错误。

修复步骤

1. 建立字符串到图片文件的映射

修正liste_portrait_photo,让它直接对应实际的图片文件名:

# 替换原liste_portrait_photo,与实际图片文件名一一对应
liste_portrait_photo = [
    "portrait_satanas.png", 
    "portrait_folle.png", 
    "portrait_sorciere.png", 
    "portrait_vieux.png"
]

2. 在lancer函数中加载对应图片并保留引用

在lancer函数里,根据配置文件保存的图片文件名动态加载图像,同时将图像对象绑定到Label的属性上,防止Python垃圾回收机制回收图像资源:

# 替换lancer函数中PILOTE 1部分的头像代码
# 加载对应图片
portrait_path = f"images/{data['Portrait pilote 1']}"
pilote1_img = ImageTk.PhotoImage(Image.open(portrait_path))
# 创建Label并绑定图像引用
portrait_pilote_1 = Label(frame1, image=pilote1_img, compound="top", border="0")
portrait_pilote_1.image = pilote1_img  # 保留引用,避免GC回收
portrait_pilote_1.place(relx=0.5, y=120, anchor="center")

3. 同理修复PILOTE 2的图片显示

# 在PILOTE 2部分添加头像加载代码
portrait_path_p2 = f"images/{data['Portrait pilote 2']}"
pilote2_img = ImageTk.PhotoImage(Image.open(portrait_path_p2))
portrait_pilote_2 = Label(frame2, image=pilote2_img, compound="top", border="0")
portrait_pilote_2.image = pilote2_img
portrait_pilote_2.place(relx=0.5, y=120, anchor="center")

4. 优化窗口切换逻辑(可选)

原代码中销毁主窗口后创建新Tk()实例的方式不规范,建议改用Toplevel子窗口并隐藏主窗口:

# 替换lancer函数开头的窗口代码
# fenetre_ppale.destroy()  # 注释销毁主窗口的代码
fenetre_ppale.withdraw()  # 隐藏主窗口
fenetre_ppale2 = Toplevel(fenetre_ppale)  # 创建子窗口

完整修改后的关键代码片段

# 全局变量部分修正
liste_portrait_photo = [
    "portrait_satanas.png", 
    "portrait_folle.png", 
    "portrait_sorciere.png", 
    "portrait_vieux.png"
]

# lancer函数中图片加载部分
def lancer():
    global frame3, frame4, frame1, fenetre_ppale2
    fenetre_ppale.withdraw()  # 隐藏主窗口而非销毁
    fenetre_ppale2 = Toplevel(fenetre_ppale)
    fenetre_ppale2.geometry("1720x1080+10+10")

    # ... 其他代码保持不变 ...

    # 读取配置数据
    with open('configcourse.json', 'r') as fic:
        data = json.load(fic)

    # PILOTE 1区域
    frame1 = Frame(fenetre_ppale2, width=573, height=800, bg="brown",  pady=10, padx=10)
    frame1.place(x=191, y=121)

    lbl_frame1 = Label(frame1, text=data['Pilote 1'], font="Futura 42 bold", padx=20, bg="brown", fg="white")
    lbl_frame1.place(relx=0.5, y=50, anchor="center")

    # 加载并显示PILOTE1头像
    portrait_path = f"images/{data['Portrait pilote 1']}"
    pilote1_img = ImageTk.PhotoImage(Image.open(portrait_path))
    portrait_pilote_1 = Label(frame1, image=pilote1_img, compound="top", border="0")
    portrait_pilote_1.image = pilote1_img
    portrait_pilote_1.place(relx=0.5, y=120, anchor="center")

    # PILOTE 2区域
    frame2 = Frame(fenetre_ppale2, width=573, height=800, bg="navy", pady=10, padx=10)
    frame2.place(x=955, y=121)
    lbl_frame2 = Label(frame2, text=data['Pilote 2'], font="Futura 42 bold", padx=20, bg="navy", fg="white")
    lbl_frame2.place(relx=0.5, y=50, anchor="center")

    # 加载并显示PILOTE2头像
    portrait_path_p2 = f"images/{data['Portrait pilote 2']}"
    pilote2_img = ImageTk.PhotoImage(Image.open(portrait_path_p2))
    portrait_pilote_2 = Label(frame2, image=pilote2_img, compound="top", border="0")
    portrait_pilote_2.image = pilote2_img
    portrait_pilote_2.place(relx=0.5, y=120, anchor="center")

    fenetre_ppale2.mainloop()

内容的提问来源于stack exchange,提问作者Lokazionel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:45:54