No se puede mostrar una imagen en Tkinter

Cuando ejecuto el progtwig, el canvas aparece pero la imagen no.

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) 

¿¿algunas ideas??

PD.

Tengo PIL versión 1.6, python 2.6 y la versión de Tkinter que viene con python 2.6

Ok, lo descubrí. Aparentemente, debido a la forma en que Python se ocupa de la eliminación de basura, las imágenes simplemente se borran. Se requiere una referencia a la imagen en el ámbito global. Este es el código de trabajo que eventualmente terminé usando:

 self.photo = PhotoImage(file="noart.ppm") self.Artwork = Label(self.frame, image=self.photo) self.Artwork.photo = self.photo self.Artwork.pack() 

que self.Artwork.photo = self.photo es la parte importante. Asegura que la imagen será mostrada.

Como se mencionó en esta respuesta y en esta pregunta y respuesta más popular y también en effbot.page

Cuando agrega un objeto PhotoImage u otro objeto de imagen a un widget de Tkinter, debe mantener su propia referencia al objeto de imagen. Si no lo haces, la imagen no siempre se mostrará.

El problema es que la interfaz Tkinter / Tk no maneja las referencias a los objetos de imagen correctamente; El widget Tk contendrá una referencia al objeto interno, pero Tkinter no. Cuando el recolector de basura de Python descarta el objeto Tkinter, Tkinter le dice a Tk que libere la imagen. Pero como la imagen está en uso por un widget, Tk no la destruye. No completamente. Solo deja en blanco la imagen, haciéndola completamente transparente …

La solución es asegurarse de mantener una referencia al objeto Tkinter,

Por ejemplo la image en el siguiente código no siempre aparecerá Si es que no se declara en el scope global:

 import tkinter as tk root = tk.Tk() def show_image(): img_label = tk.Label(root) image = tk.PhotoImage(file="test.png") img_label['image'] = image img_label.pack() show_image() root.mainloop() 

mientras que en el siguiente ejemplo, img_label.image se declara globalmente, como un atributo adjunto a nuestra muy img_label en este ejemplo, y se mostrará :

 import tkinter as tk root = tk.Tk() def show_image(): img_label = tk.Label(root) img_label.image = tk.PhotoImage(file="test.png") img_label['image'] = img_label.image img_label.pack() show_image() root.mainloop() 

Sin embargo, sigue siendo extraño ya que img_label tampoco se declara globalmente. Una forma menos confusa sería agregar global image como la primera línea de show_image .

Si alguien más tiene un problema similar, puede probar esta solución codificada:

 import Image import Tkinter as tk def cleanhex(x): return str(hex(x))[-2:] def renderimage(target,data,w,h): canvas = tk.Canvas(target,width=w,height=h) canvas.pack() for x in range(w): for y in range(h): c = "#" + cleanhex(data[x,y][0]) + cleanhex(data[x,y][1]) + cleanhex(data[x,y][2]) canvas.create_line(x,y,x+1,y+1,fill=c) im = Image.open("whatever.whatever") renderimage(root,im.load(),im.size[0],im.size[1])