tkinter image not displaying despite not being collected

65 views Asked by At

the following won t display anything:

def pic(name):
    def p(image=[]): #keep a reference to the image, but only load after creating window
        if not image: 
            image.append(PhotoImage("../pic/small/"+name+".png")) 
        return image[0]
    def do(canvas, point, angle, size, fill, outline):
        canvas.create_image(*point, image=p(), tag="visual")
    return do

flame = pic("flame")

flame(canvas, (100, 200), 0, 30, "red", "blue")

The second time I m calling flame, p still remembers its image. No Exceptions occur, yet the image doesn t show up.

however:

_pic2 = PhotoImage(file="../pic/small/flame.png")
canvas.create_image(300, 200, image=_pic2)

does work

(I m aware there are some unused arguments, but pic needs the same signature as other functions that need them

def do(canvas, point, *_):

would be just as good)

(pic, flame, _pic2, canvas) are global

1

There are 1 answers

1
tobias_k On BEST ANSWER

The problem seems not to be the image being garbage collected at all. You are just missing the file parameter name, thus the path is used as the image's "name" instead.

Using PhotoImage(file="../pic/small/"+name+".png") should fix it.

However, speaking of garbage collection, you don't actually need the inner p function with the list parameter. This is one of the rare cases where you can just define the PhotoImage as a local variable in the function, as it will remain in the scope of the do function even after the pic function has exited, and thus will not be garbage collected.

def pic(name):
    img = PhotoImage(file="../pic/small/"+name+".png")
    def do(canvas, point, angle, size, fill, outline):
        canvas.create_image(*point, image=img, tag="visual")
    return do

(It will be collected when flame is collected, though, but the same is true for your approach. But as you said flame is global, this should not be a problem.)