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

Tkinter点击按钮报错_tkinter.TclError: image "pyimage2"不存在如何解决

问题原因

这个报错是Tkinter的经典问题,根源是PhotoImage类型的图片对象被Python垃圾回收机制自动清理:
Tkinter内部不会额外持有PhotoImage对象的引用,哪怕你已经将图片赋值给按钮的image属性。如果图片对象没有被其他长生命周期的变量/对象持有,Python会在变量作用域失效后自动回收该图片对应的内存资源,后续Tkinter渲染控件时找不到对应的图片资源,就会抛出image "pyimageX" doesn't exist的错误。

你代码里的问题出在alphabet()函数内部:你创建的picAlphabetMaj是函数局部变量,函数执行结束后该变量的引用就会失效,你写的picAlphabetMaj.pictureAlphabetMaj = pictureAlphabetMaj是把原PIL图片绑定到了即将被回收的PhotoImage对象本身,根本起不到持有引用的作用。

修复方案

只需要把PhotoImage对象绑定到使用它的按钮组件的属性上即可,按钮被Canvas持有不会被回收,对应的图片引用也就会一直存在:
把alphabet()函数里的这行代码:

picAlphabetMaj.pictureAlphabetMaj = pictureAlphabetMaj

替换为:

boutonAlphabetMaj.img = picAlphabetMaj

修改后的完整alphabet()函数如下:

def alphabet() :
    canvas.delete("boutonAlphabet")
    # Bouton Alphabet Majuscule
    pathAlphabetMaj = os.path.join("test/alphabetMaj.png")
    pictureAlphabetMaj = Image.open(pathAlphabetMaj)
    picAlphabetMaj = ImageTk.PhotoImage(pictureAlphabetMaj)
    boutonAlphabetMaj = tk.Button(canvas, image=picAlphabetMaj, borderwidth=0, bg="#383838", activebackground="#4a4a4a", cursor="hand2")
    # 改动在这里:将图片对象绑定到按钮的属性上,避免被回收
    boutonAlphabetMaj.img = picAlphabetMaj
    boutonAlphabetMaj.bind("<Enter>", lambda e: boutonAlphabetMaj.config(fg='#383838', bg='#3f3f3f'))
    boutonAlphabetMaj.bind("<Leave>", lambda e: boutonAlphabetMaj.config(fg='#3f3f3f', bg='#383838'))
    canvas.create_window(200, 500, window=boutonAlphabetMaj, tags=("boutonAlphabetMaj"))
补充注意

所有在局部作用域创建的Tkinter PhotoImage对象,都需要手动绑定到长生命周期对象(比如窗口、Canvas、控件本身)的属性上,或者存到全局的列表/字典中,否则都会触发该类报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:54:06