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

如何在多个Customtkinter窗口中复用同一张图片?

问题:Customtkinter多窗口图片显示报错:image "pyimage2" doesn't exist

问题背景

使用Customtkinter构建GUI,主窗口中通过PIL库在CTkLabel里正常显示同目录下的logo图片,但在设置窗口中执行相同逻辑时触发错误。

主窗口可运行代码

class MainWindow(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.geometry("700x400")

        self.img_frame = ctk.CTkFrame(self)
        self.img_frame.pack(pady=10, padx=10, fill='x')

        self.logo = ctk.CTkImage(light_image=Image.open("./logo.png"), size=(250, 80))
        print(self.logo)

        self.img_label = ctk.CTkLabel(self.img_frame, image= self.logo, compound="left", text="")
        self.img_label.grid(pady=10, padx=10, column=0, row=0, sticky="w")

设置窗口尝试代码

class SetupWindow(ctk.CTk):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.geometry("700x370")

        self.title_frame = ctk.CTkFrame(self, height=100, width=680)
        self.title_frame.grid(row=0, column=0, padx=10, pady=10, sticky='news')

        self.logo = ctk.CTkImage(light_image=Image.open("./logo.png"), size=(250, 80))
        print(self.logo)

        self.img = ctk.CTkLabel(self.title_frame, image= self.logo, compound="left", text="")
        self.img.grid(pady=10, padx=10, column=0, row=0, sticky="w")

报错信息

Exception in Tkinter callback
Traceback (most recent call last):
in __init__
    self.img = ctk.CTkLabel(self.title_frame, image= self.logo, compound="left", text="")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: image "pyimage2" doesn't exist

解决方案

这个错误的核心原因是:Tkinter不允许在多个独立的CTk(即Tk根窗口)实例间共享图片资源。每个CTk实例对应一个独立的Tcl解释器上下文,图片资源绑定在创建它的上下文里,无法跨上下文访问。

推荐方案:将设置窗口改为CTkToplevel子窗口

把设置窗口的继承类从ctk.CTk改为ctk.CTkToplevel,并在初始化时传入主窗口作为父组件,这样设置窗口会共享主窗口的Tcl上下文,图片资源可以正常加载:

class SetupWindow(ctk.CTkToplevel):
    def __init__(self, parent):
        super().__init__(parent)  # 传入父窗口作为参数
        self.parent = parent
        self.geometry("700x370")

        self.title_frame = ctk.CTkFrame(self, height=100, width=680)
        self.title_frame.grid(row=0, column=0, padx=10, pady=10, sticky='news')

        self.logo = ctk.CTkImage(light_image=Image.open("./logo.png"), size=(250, 80))
        print(self.logo)

        self.img = ctk.CTkLabel(self.title_frame, image=self.logo, compound="left", text="")
        self.img.grid(pady=10, padx=10, column=0, row=0, sticky="w")

备选方案(不推荐):强制隔离上下文

如果必须使用独立的CTk窗口,需要在创建第二个窗口前重置Tkinter的图片ID,或者确保每个窗口的图片资源完全独立加载并绑定到自身上下文。但这种方法容易引发其他Tkinter上下文冲突,不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:45:13