如何使用Python Tkinter更有效地创建图像显示器?

问题描述

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 imagelabel.image = photo。无论哪种方式,您都只需要保留一个引用,以免被垃圾收集。

global对于OOP可能不是有效的,因为这可能会在以后引起一些问题,这是我所听到的,因此您可以保留label.image = photo上的引用。

来自effbot.org:

问题在于Tkinter / Tk界面无法正确处理对Image对象的引用; Tk小部件将保留对内部对象的引用,但Tkinter不会。当Python的垃圾收集器丢弃Tkinter对象时,Tkinter告诉Tk释放图像。但是由于小部件正在使用图片,因此Tk不会销毁它。不完全的。它只是使图像空白,使其完全透明。

希望这可以解决您的疑问。

欢呼