问题描述
import tkinter as tk
from PIL import ImageTk,Image
root = tk.Tk()
def photogetter():
###global photo
photo= ImageTk.PhotoImage(Image.open("smiley.png").resize((320,240)))
label =tk.Label(root,image=photo)
canv.create_window((320,240),window=label)
canv = tk.Canvas(root,width=640,height=480)
canv.grid(row=0,column=0)
button = tk.Button(root,text="Button",command=photogetter)
button.grid(row=1,column=0)
root.mainloop()
除非我在函数中将 photo 变量声明为全局变量,否则此代码无效。有人可以解释一下为什么我必须将 photo 变量声明为全局变量吗?对我来说,使用局部变量看起来更有效,但这不起作用。
解决方法
这是因为当photo
不是global
时,它是由python垃圾回收器收集的垃圾,因此您需要保留对图像的引用,可以这样说global image
或label.image = photo
。无论哪种方式,您都只需要保留一个引用,以免被垃圾收集。
global
对于OOP可能不是有效的,因为这可能会在以后引起一些问题,这是我所听到的,因此您可以保留label.image = photo
上的引用。
来自effbot.org:
问题在于Tkinter / Tk界面无法正确处理对Image对象的引用; Tk小部件将保留对内部对象的引用,但Tkinter不会。当Python的垃圾收集器丢弃Tkinter对象时,Tkinter告诉Tk释放图像。但是由于小部件正在使用图片,因此Tk不会销毁它。不完全的。它只是使图像空白,使其完全透明。
希望这可以解决您的疑问。
欢呼