Why doesn't a local name with a PhotoImage object work, for a tkinter label image?

筅森魡賤 提交于 2020-04-30 11:39:27

问题


I have created a python class which inherits Tk from tkinter library. I want to add a label with an image to it but it only works when I create a Photoimage as variable to 'self'.

This code works:

class HMIDrawer(Tk):

    def __init__(self):
        super().__init__()

        self.frame = Frame(self)
        self.img = PhotoImage(file='resources/platoontomtom_empty.png')
        self.label = Label(self.frame, image=self.img, bg='white')
        self.label.pack()
        self.frame.pack()
        self.mainloop()

And this code doesn't work:

class HMIDrawer(Tk):

    def __init__(self):
        super().__init__()

        self.frame = Frame(self)
        img = PhotoImage(file='resources/platoontomtom_empty.png')
        self.label = Label(self.frame, image=img, bg='white')
        self.label.pack()
        self.frame.pack()
        self.mainloop()

Can anyone explain why the first code does work and the second code doesn't?


回答1:


PhotoImage reads the image data from file and stores it in memory as a pixel buffer. The reference of this buffer has to be persistent as long as the application runs (or at least, as long the Label widget showing the image exists).

If you put the result of PhotoImage in a local variable (e.g. img, as in the second code), the garbage collector is likely to destroy the data referenced by this local variable. On the other hand, if you store the reference of your pixel buffer in an attribute (e.g. self.img, as in the first code) the garbage collector will not destroy your data as long as self exists, which means as long as the application runs...

If your GUI uses many images, a usual practice is to create an attribute self.images that puts all required images either in a tuple or a dictionary (whether you prefer indexing them by numbers or by strings), that ensures that all images will be kept in memory.



来源:https://stackoverflow.com/questions/49797743/why-doesnt-a-local-name-with-a-photoimage-object-work-for-a-tkinter-label-imag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!