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
相关产品推荐
相关产品推荐

