无法在Tkinter中显示图像

Jos*_*unz 4 python image tkinter

当我运行该程序时,画布显示但图像不显示.

canvas = Canvas(frame, width = 128, height = 128, bg= 'white')
    image_data = Image.open('NoArt.gif')
    ppm_f = ImageTk.PhotoImage(image_data)
    canvas.create_image(0, 0, image = ppm_f, anchor = NW)
    canvas.pack(side=BOTTOM)
Run Code Online (Sandbox Code Playgroud)

有任何想法吗??

PS.

我有PIL版本1.6,python 2.6和python 2.6附带的Tkinter版本

Jos*_*unz 10

好吧,我想通了.显然,由于python处理垃圾处理的方式,图片才会被删除.需要在全局范围内引用图像.这是我最终使用的工作代码:

self.photo = PhotoImage(file="noart.ppm")
    self.Artwork = Label(self.frame, image=self.photo)
    self.Artwork.photo = self.photo
    self.Artwork.pack()
Run Code Online (Sandbox Code Playgroud)

self.Artwork.photo = self.photo是重要的部分.它确保显示图像.


Nae*_*Nae 8

正如这个答案这个更受欢迎的问答以及effbot.page中提到的

\n\n
\n

当您将 PhotoImage 或其他 Image 对象添加到 Tkinter 小部件时,\n 您必须保留自己对图像对象的引用。如果您不这样做,则图像将始终显示。

\n\n

问题是 Tkinter/Tk 接口不能正确处理对 Image 对象的引用;Tk 小部件将保存对内部对象的引用,但 Tkinter 不会。当 Python\xe2\x80\x99s 垃圾收集器\n 丢弃 Tkinter 对象时,Tkinter 告诉 Tk 释放图像。\n 但由于图像正在被小部件使用,Tk 不会\xe2\x80\x99 销毁它。不完全。它只是将图像清空,使其完全\n 透明\xe2\x80\xa6

\n\n

解决方案是确保保留对 Tkinter\n 对象的引用,

\n
\n\n

例如image下面的代码won\xe2\x80\x99t 总是出现,如果有的话,因为它没有在全局范围内声明:

\n\n
import tkinter as tk\n\nroot = tk.Tk()\n\ndef show_image():\n    img_label = tk.Label(root)\n    image = tk.PhotoImage(file="test.png")\n    img_label[\'image\'] = image\n\n    img_label.pack()\n\n\nshow_image()\nroot.mainloop()\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n

而在下面的示例中img_label.image是全局声明的,作为附加到我们的本示例中的属性img_label,并且将显示:

\n\n
import tkinter as tk\n\nroot = tk.Tk()\n\ndef show_image():\n    img_label = tk.Label(root)\n    img_label.image = tk.PhotoImage(file="test.png")\n    img_label[\'image\'] = img_label.image\n\n    img_label.pack()\n\n\nshow_image()\nroot.mainloop()\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n

但这仍然很奇怪,因为img_label也没有全局声明。一种不太令人困惑的方法是将global image其作为第一行添加到show_image.

\n