插入多个图像Tkinter

时间:2016-03-09 00:17:44

标签: python tkinter

我在用于tkinter的Listbox小部件中插入多个图像时遇到问题。当我插入新图像时,前一个图像消失了。我该怎么办?以下是我遇到问题的代码:

img = PhotoImage(file = Client.dir + "emo1.gif")
self.listBox.insert(END, sender)
self.listBox.image_create(END, image=img)
self.listBox.insert(END, "\n")
self.listBox.yview(END)

1 个答案:

答案 0 :(得分:2)

正如the documentation所述:(和comment by @BryanOakley

  

然后,可以在某些小部件(例如标签,按钮,菜单)支持image选项的任何地方使用图像对象。在这些情况下, Tk不会保留对图像的引用。当删除对图像对象的最后一次Python引用时,图像数据也会被删除,并且Tk将在任何地方显示一个空框使用了图像。

虽然suggestion by @BryanOakley 绝对是最简单的解决方案,但它可以防止未使用的图像被垃圾收集,这可能是不受欢迎的。

注意:我建议的解决方案是假设self.listBoxText窗口小部件,因为Listbox窗口小部件没有image_create方法。如果您使用的是其他类型的小部件,那么您仍然可以创建一个类似的类来处理引用所使用的图像。

您可以创建Text的子类,通过覆盖相关方法(image_createdelete是最重要的)来保留对插入图像的引用:

from tkinter import Text #, PhotoImage, Tk

class Text_autoReferenceImage(Text):
    def __init__(self,*varg,**kw):
        self.images = {}
        Text.__init__(self,*varg,**kw)

    def image_create(self,index,**options):
        img = options.get("image",None)
        name = Text.image_create(self,index,**options)
        if img is not None:
            self.images[name] = img #this may remove previous reference with same name but different image
        return name

    def delete(self,*varg,**kw):
        Text.delete(self,*varg,**kw)
        self.clean_up_images()

    def clean_up_images(self):
        """deletes reference to all images that are no longer present in Text widget (called by .delete())"""
        images_still_in_use = self.image_names()
        for name in set(self.images.keys()): #need to put .keys() into a set in python3 or it complains about dictionary changing size during iteration
            if name not in images_still_in_use:
                del self.images[name]

    def destroy(self):
        self.images.clear() #remove all references to own images
        return Text.destroy(self)

然后,如果self.listBox是此类的实例而不是Text,它将为您处理图像引用。