PyQT5打包:用PyInstaller遇到的坑
在使用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
文件