Tkinter类新建窗口函数触发TclError:image不存在问题求解
问题原因
该报错本质仍是图片引用异常,结合保留窗口创建功能就报错的特征,大概率是以下两个问题导致:
- 你自定义的
Yelp_screen_start、Insta_screen_start两个子窗口类内部,错误创建了新的tk.Tk()实例,而非使用传入的Toplevel作为容器。Tkinter中只要存在多个Tk()根实例,不同实例下的PhotoImage资源ID不互通,就会抛出找不到图片的错误。 - 你代码中存在重复读取图片的冗余操作,且如果子窗口中也有未绑定到实例属性的
PhotoImage对象,会触发全局的图片引用回收逻辑,间接影响启动页的图片引用有效性。
修复方案
按以下三步修改即可:
- 第一步:检查修改
Yelp_screen_start、Insta_screen_start类的初始化逻辑,确保内部没有再创建tk.Tk()实例,所有组件都挂载到你传入的Toplevel对象上。
错误写法(需要删除):
class Yelp_screen_start: def __init__(self, master): # 不能在子窗口重复创建Tk实例 self.master = tk.Tk()
正确写法:
class Yelp_screen_start: def __init__(self, master): # 直接用传入的Toplevel对象作为父容器 self.master = master # 后续所有组件都挂载到self.master上即可
- 第二步:优化启动页的图片读取逻辑,避免重复打开图片,同时删掉冗余的canvas重复打包代码:
class Start_Screen: def __init__(self, master): self.master = master # 只读取一次图片,后续复用该对象 image = PIL.Image.open('start_screen_pic.png') WIDTH, HEIGHT = image.size self.master.geometry('{}x{}'.format(WIDTH, HEIGHT)) self.canvas = tk.Canvas(self.master, width=WIDTH, height=HEIGHT) self.canvas.pack(side='top', fill='both', expand='yes') # 直接用已打开的image对象转PhotoImage,无需重复open self.start_img = ImageTk.PhotoImage(image) self.canvas.create_image(0, 0, image=self.start_img, anchor='nw') self.button1 = tk.Button(self.master, text = 'Yelp review statistics', width = 25, command = self.Yelp_screen) self.button2 = tk.Button(self.master, text = 'Instagram post analysis', width = 25, command = self.Insta_screen) self.button1.pack() self.button2.pack() def Yelp_screen(self): self.newWindow = tk.Toplevel(self.master) self.app = Yelp_screen_start(self.newWindow) def Insta_screen(self): self.newWindow = tk.Toplevel(self.master) self.app = Insta_screen_start(self.newWindow)
- 第三步:如果子窗口中也使用了
PhotoImage加载图片,务必将所有图片对象绑定到子窗口的实例属性上,不要用局部变量存储图片对象,避免被Python垃圾回收。
内容的提问来源于stack exchange,提问作者Gutenberg
相关产品推荐
相关产品推荐

