2016-03-09 150 views
1

我無法在tkinter的Listbox Widget中插入多張圖片。當我插入新圖像時,前一個圖像消失了。我該怎麼辦?下面是我在使用麻煩的代碼:插入多張圖片Tkinter

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) 
+2

如果你沒有保存對每個的引用,他們可能被垃圾收集。 –

+0

我該怎麼辦?如何引用他們每個人? – user6036956

+0

即時通訊創建聊天消息在哪裏你可以發送圖像 – user6036956

回答

2

作爲the documentation狀態:無論一個image選項是由一些小部件支持(和comment by @BryanOakley

然後圖像對象可以被使用(例如標籤,按鈕,菜單)。在這些情況下,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它將爲您處理圖像參考。

+1

感謝麥當勞詹森。現在我知道事情如何在Python中工作。非常豐富的答案。謝謝 :) – user6036956