tkinter和库PhotoImage

时间:2018-12-13 17:38:08

标签: python python-3.x tkinter photoimage

此代码有效:

img = PhotoImage(file="Image.gif")

Label(root, image=img).pack()

这种方式怎么行不通?

Label(root, image=PhotoImage(file="Image.gif")).pack()

不可能将所有内容都放在一行吗?

2 个答案:

答案 0 :(得分:1)

问题不是关于语法的问题,而是关于垃圾回收的问题。以您的缩写形式:

Label(root, image=PhotoImage(file="Image.gif")).pack()

指向PhotoImage()返回的图像的指针永远不会保存,因此图像会被垃圾回收并且不会显示。以您的较长格式:

img = PhotoImage(file="Image.gif")

Label(root, image=img).pack()

您正在握住指向图像的指针,因此一切正常。您可以通过以下方式说服自己:将工作代码包装在一个函数中,并使img在该函数中是本地的:

from tkinter import *

root = Tk()

def dummy():
    img = PhotoImage(file="Image.gif")

    Label(root, image=img).pack()

dummy()

mainloop()

现在,它不再显示,因为当函数返回并且图像被垃圾回收时,img消失了。现在,返回图像并将返回的值保存在变量中:

def dummy():
    img = PhotoImage(file="Image.gif")

    Label(root, image=img).pack()

    return img

saved_ref = dummy()

您的图像再次起作用!常见的解决方法如下:

def dummy():
    img = PhotoImage(file="Image.gif")

    label = Label(root, image=img)
    label.image_ref = img  # make a reference that persists as long as label

    label.pack()

dummy()

但是您可以看到我们已经远离单线!

答案 1 :(得分:0)

在第一个版本中,img保留对图像的引用。

在第二个版本中,没有对该图像的引用,并且pack()返回None