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

Tkinter程序点击按钮显示图片无报错但不显示的问题求助

解决Tkinter点击按钮显示图片不生效的问题

我来帮你搞定这个问题!你的代码逻辑其实没问题,但漏掉了一个Tkinter里很容易踩的坑——PhotoImage对象会被Python的垃圾回收机制自动清理,除非有一个持久的引用指向它。

问题根源

在你的def_btn1函数里,test = ImageTk.PhotoImage(image1)是个局部变量。当函数执行完毕后,Python会自动回收这个局部变量占用的内存,哪怕你把它赋值给了Label的image参数也没用——Tkinter内部的引用不会阻止Python的垃圾回收,所以图片就“消失”了,而且不会报错。

另外你原代码里还有个小错误:window = tk.mainloop()是不对的,mainloop()不需要赋值给变量,直接调用window.mainloop()即可。

修正方案(推荐第一种)

方案1:把PhotoImage绑定到Label的属性上

这是最优雅的解决方式,不用全局变量,直接让Label自己持有图片的引用:

import tkinter as tk
from PIL import ImageTk, Image

window = tk.Tk()

def def_btn1():
    # 打开并调整图片大小
    image1 = Image.open("csdl.png")
    # 注意:Image.ANTIALIAS在PIL 9.1.0+已被弃用,推荐用Resampling.LANCZOS
    image1 = image1.resize((710, 400), Image.Resampling.LANCZOS)
    # 创建PhotoImage对象
    test = ImageTk.PhotoImage(image1)
    # 创建Label并设置图片
    lbl2 = tk.Label(image=test)
    # 关键步骤:把PhotoImage绑定到Label的属性上,保持引用
    lbl2.image = test
    lbl2.pack()

btn1 = tk.Button(text="click to show", relief=tk.RIDGE, width=15, font=(12), command=def_btn1)
btn1.pack()

window.mainloop()

方案2:使用全局变量(不推荐,除非必要)

如果你不想修改Label的属性,也可以把PhotoImage声明为全局变量,让它在函数执行完后依然存在:

import tkinter as tk
from PIL import ImageTk, Image

window = tk.Tk()
# 声明全局变量存储图片对象
test = None

def def_btn1():
    global test
    image1 = Image.open("csdl.png")
    image1 = image1.resize((710, 400), Image.Resampling.LANCZOS)
    test = ImageTk.PhotoImage(image1)
    lbl2 = tk.Label(image=test)
    lbl2.pack()

btn1 = tk.Button(text="click to show", relief=tk.RIDGE, width=15, font=(12), command=def_btn1)
btn1.pack()

window.mainloop()

额外提示

  • 确认图片路径确实正确:如果是相对路径,要确保图片和你的Python脚本在同一个文件夹里;或者直接用绝对路径(比如C:/images/csdl.png)测试。
  • 如果你用的是较新版本的PIL,Image.ANTIALIAS已经被标记为弃用,换成Image.Resampling.LANCZOS可以避免警告,效果是一样的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:22:32