前言 之前py打包的exe一直是不涉及圖片等資源的,直到我引入圖片後打包,再雙擊exe發現直接提示未找到資源。 分析 我py代碼中的圖片引入使用的是項目相對路徑,打包時pyinstaller只會引入py模塊,這種路徑引入的資源其實是不會打包進exe的。有人想的是可以直接將資源放到exe旁邊,但這不是 ...
前言
之前py打包的exe一直是不涉及圖片等資源的,直到我引入圖片後打包,再雙擊exe發現直接提示未找到資源。
分析
我py代碼中的圖片引入使用的是項目相對路徑,打包時pyinstaller只會引入py模塊,這種路徑引入的資源其實是不會打包進exe的。有人想的是可以直接將資源放到exe旁邊,但這不是最優雅的方法,你發佈exe還得給人家一堆相關資源文件,其實想要解決此類無法打包資源的問題其實只需要做兩件事:1、修改spec打包配置。2、動態獲取資源路徑。
步驟
- 這是我的項目結構
圖片資源在src下的img目錄中,我在main.py中需要使用其中的圖片。
- 在main.py中定義動態獲取資源路徑的函數
#獲取資源路徑
def getPath(relative_path):
# 判斷是否為frozen狀態(即為打包運行狀態)
if getattr(sys, 'frozen', False):
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)# 返回真實路徑
我們需要先獲取項目當前狀態,判斷是否為frozen狀態(即為打包運行狀態),是的話先獲取 MEIPASS路徑(MEIPASS為雙擊exe時系統分配的臨時工作目錄),不是的話直接獲取絕對路徑,最後返回真實路徑。
- 在需要獲取路徑的地方直接使用getPath即可,比如我要修改exe窗體圖標,這樣即可:
root.iconbitmap(getPath(os.path.join("src","img/logo.ico")))
我要在tk界面使用Label添加圖片,這樣即可:
imgImg = ImageTk.PhotoImage(Image.open(getPath(os.path.join("src","img/img.png"))))
Label(imgFrame,image=imgImg).grid(column = 0,row = 0)
- 最後修改spec打包配置(不懂spec的看這兒:https://xiblogs.top/?id=57 )中Analysis的datas:
datas中第一個src表示你需要打包的資源目錄,第二個src表示打包成exe後雙擊exe時釋放資源在MEIPASS目錄下的具體位置,這是我打包運行時系統釋放資源的位置,你可以看到src就在這裡,exe中的圖片也載入進界面了:
結語
值得註意的是該目錄打開exe即生成,關閉exe即刪除,不可在此長久保存文件。類似於我篇文章(https://xiblogs.top/?id=65 )修改exe圖標使用base64轉換ico的邏輯,當然,你現在可以直接使用MEIPASS來處理了。
原文鏈接:https://xiblogs.top/?id=66