在使用PyQT5製作GUI時,經常需要用到本地資源,然而打包成exe後,發送給其他小夥伴運行失敗。原因與pyinstaller運行機制有關。

Pyinstaller 可以將資源文件一起打包到exe中,當exe在運行時,會生成一個臨時文件夾,程序可通過sys._MEIPASS訪問臨時文件夾中的資源

from PyQt5.Qt import QWidget, QApplication, QComboBox,QPalette,QBrush,QPixmap
import pandas as pd
import sys,os

class MyWin(QWidget):
def __init__(self):
super().__init__()
self.resize(300, 200)
combox = QComboBox(self) # 創建下拉按鈕
combox.setGeometry(50, 50, 100, 20) # 設置下拉按鈕(x,y,width,height)
filePath = self.file_path("test.xlsx")
print(filePath)
data = pd.read_excel(filePath) # 打開Excel文件
combox.addItems(data[城市]) # 設置下拉內容

def resizeEvent(self, event): # 尺寸修改事件
palettel = QPalette()
Background = self.file_path("timg.jpg") # 資源文件地址
palettel.setBrush(self.backgroundRole(),
QBrush(QPixmap(Background).scaled(self.width(), self.height()))) # 設置背景圖片
self.setPalette(palettel)

def file_path(self,filename): # 生成資源文件目錄訪問路徑
relative_path = os.path.join("resource", filename)
if getattr(sys, frozen, False): # 判斷sys中是否存在frozen變數,
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)

if __name__ == __main__:
app = QApplication(sys.argv)
win = MyWin()
win.show()
sys.exit(app.exec_())

if getattr(sys, frozen, False):

程序打包成exe的時,會將一個變數frozen注入到sys中,這裡使用判斷,檢測sys是否有frozen這個變數,如果有,就使用sys._MEIPASS訪問臨時文件夾路徑,如果沒有,就使用當前路徑,當程序不管是以PyInstaller打包後形式運行,還是本地測試,都能找到正確的資源路徑。

先將上面測試代碼生成spec文件

配置spec文件:在datas中表明需要將哪些文件添加到exe,在臨時文件中是什麼名字

生成EXE文件,pyinstaller -F test.spec ,注意這裡是執行.spec文件

打包成功後,注意看調用的資源路徑


so easy

官方說明:pythonhosted.org/PyInst

相关文章