tkinter的按鈕幕屹、標(biāo)簽等都可以用圖標(biāo)顯示蓝丙,但是可能存在不顯示的問題。當(dāng)然包括多種原因望拖,比如路徑不對渺尘、圖片格式不對等。這些都不是本文要解決的说敏。本文所說的不顯示具體指鸥跟,
1.在一個函數(shù)內(nèi)生成圖標(biāo)
def createImageProcess():
scan1 = icon("skip_forward_16x16.gif").get()
btn1 = tk.Button(master,image = scan1, text="new")
(請暫且忽略icon,這是我自己定義的一個圖片導(dǎo)入類盔沫。)
2.在一個類的方法內(nèi)生成圖標(biāo)
class A:
def createImageProcess(self):
scan1 = icon("skip_forward_16x16.gif").get()
btn1 = tk.Button(master,image = scan1, text="new")
3.這一種最為詭異医咨。大概的情況是我已經(jīng)生成了有圖標(biāo)的按鈕,然后再在界面上修改時迅诬,原有的圖標(biāo)——嗖——不見了腋逆。就像下面這樣
在圖1中圖標(biāo)還在,等生成第二個tab的時候侈贷,圖標(biāo)不見了(請忽略圖2中的藍色惩歉,那是我解決問題以后出現(xiàn)的)
對于前兩種情況產(chǎn)生的原因已經(jīng)有一些博文解釋了,也給出了解決方案俏蛮。原因是python的垃圾回收機制撑蚌。當(dāng)函數(shù)運行結(jié)束后,其中的局部變量被回收了搏屑,圖片被銷毀争涌。所以,解決方案就是阻止圖片被銷毀辣恋。對于第一種亮垫,將圖片提到函數(shù)外面
scan1 = icon("skip_forward_16x16.gif").get()
def createImageProcess():
btn1 = tk.Button(master,image = scan1, text="new")
第二種,將圖片寫成類屬性
class A:
def createImageProcess(self):
self.scan1 = icon("skip_forward_16x16.gif").get()
btn1 = tk.Button(master,image = self.scan1, text="new")
但是對于第三種伟骨,怕是比較詭異了饮潦。我是頭一次見到,大概你也是吧携狭。我猜想也還是被回收了继蜡。
如果是小一點的程序,用上邊的方法應(yīng)該夠了。但是對于一個復(fù)雜的程序稀并,上邊的方法始終感覺有些不完美仅颇。所以,完美解決這個問題也就成了本文的主旨碘举。
要想阻止被回收忘瓦,一種方法是定義全局變量。當(dāng)然這絕對不是完美的方案殴俱。還有一種就是用一個單例政冻。單例是替換全局變量的一個套路解法。但是這里還有一些變化线欲。因為我們的圖片有很多個明场。所以需要修改一下。先上代碼
import os
import tkinter as tk
class icon(object):
_instance = {}
def __init__(self, name):
self.path = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "icons",
name)
@classmethod
def instance(cls, name):
if name not in icon._instance.keys():
i = icon(name)
icon._instance[name] = i.get()
return icon._instance[name]
def get(self):
return tk.PhotoImage(file = self.path)
這是一個基礎(chǔ)版本的單例寫法李丰。不同之處在于instance方法中傳入了圖片名稱苦锨。用一個公有變量_instance保存了所有已導(dǎo)入的圖片。當(dāng)已經(jīng)導(dǎo)入時趴泌,直接返回舟舒。沒有導(dǎo)入時,才用tk.PhotoImage導(dǎo)入嗜憔。
這個方案用起來很方便秃励。所有的圖片保存在icons文件夾下。導(dǎo)入的時候只需要
tk.Button(master,
image = icon.instance("file_(add)_16x16.gif"),
text="new")
隨便在哪個函數(shù)吉捶、哪個類的方法里用夺鲜,都不存在問題了。
要說這個方案也存在一點瑕疵呐舔。在多線程的時候圖片可能重復(fù)導(dǎo)入币励。要修改得加線程鎖。但是珊拼,我們只是讀取圖片食呻。重復(fù)導(dǎo)入一張圖片也沒什么大礙。簡簡單單的挺美澎现。
Beautiful仅胞!用你肉嘟嘟的小手給我點個贊吧。