Python - iconos en tkinter

 
Vista:
Imágen de perfil de Víctor
Val: 18
Ha disminuido su posición en 4 puestos en Python (en relación al último mes)
Gráfica de Python

iconos en tkinter

Publicado por Víctor (9 intervenciones) el 02/11/2019 11:44:47
Hola:

NOTA: Escribiendo esta pregunta he descubierto por qué ocurre esto y cómo solucionarlo. La dejo por si a alguien le ha ocurrido lo mismo.

LA DUDA ERA:

Estoy recientenmente trabajando con python y tkinter. Quiero poner un icono en una parte de un formulario. Hago lo siguiente:
1
2
3
4
5
6
7
8
9
10
11
12
13
import tkinter as tk
 
ventana = tk.Tk()
ventana.geometry("400x400")
 
img = tk.PhotoImage(file="icono.png")
etiquetaIcono = tk.Label(ventana,image=img)
etiquetaIcono.grid(row=0,column=0)
 
otraEtiqueta = tk.Label(ventana, text="Otra etiqueta")
otraEtiqueta.grid(row=1,column=0)
 
ventana.mainloop()
Funciona como se espera: muestra el icono y debajo "Otra etiqueta".

Pero si la creación de la etiqueta con imagen la meto en un método:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import tkinter as tk
 
def icono(ventana):
    img = tk.PhotoImage(file="icono.png")
    etiquetaIcono = tk.Label(ventana,image=img)
    etiquetaIcono.grid(row=0,column=0)
 
ventana = tk.Tk()
ventana.geometry("400x400")
 
icono(ventana)
 
otraEtiqueta = tk.Label(ventana, text="Otra etiqueta")
otraEtiqueta.grid(row=1,column=0)
 
ventana.mainloop()
No da ningún error pero la imagen aparece en blanco.

LA RESPUESTA:

Obtenida de: effbot.org en https://effbot.org/tkinterbook/photoimage.htm

Dice literalmente:

Note: When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.

To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:

label = Label(image=photo)
label.image = photo # keep a reference!
label.pack()

Traducción:
Nota: Cuando Python recolecta basura de un objeto PhotoImage (por ejemplo, cuando regresa de una función que almacenó una imagen en una variable local), la imagen se borra incluso si está siendo mostrada por un widget Tkinter.

Para solucionar esto, el programa debe mantener una referencia extra a la imagen. Una forma simple de hacer esto es asignar la imagen a un atributo de widget, como este:

Entonces se puede hacer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import tkinter as tk
 
def icono(ventana,file=""):
    img = tk.PhotoImage(file=file)
    etiquetaIcono = tk.Label(ventana,image=img)
    etiquetaIcono.image = img # <<<<<<<<<<<<<<<< Esta es la linea añadida
    etiquetaIcono.grid(row=0,column=0)
 
ventana = tk.Tk()
ventana.geometry("400x400")
 
icono(ventana,file="icono.png")
 
otraEtiqueta = tk.Label(ventana, text="Otra etiqueta")
otraEtiqueta.grid(row=1,column=0)
 
ventana.mainloop()

Que funciona perfectamente.

DISCULPAS por lo extenso del mensaje.

Saludos de Víctor.-
Saludos de Víctor.-
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
1
Responder