1. 程式人生 > >wxPython開發總結---將Python原始碼打包成exe可執行檔案

wxPython開發總結---將Python原始碼打包成exe可執行檔案

python的原始碼要在沒有安裝/配置Python相關開發環境的電腦上執行,那麼就需要使用工具對原始碼進行打包,在windows上執行則必須打包成exe可執行檔案,現在常用的打包工具有:

py2exe,PyInstaller以及cx-Freeze0

PyInstaller打包太慢,過程太長;

cx-Freeze可以說飛速打包;

py2exe打包相對比較麻煩,需要另外寫一個Python的指令碼檔案.

下面使用py2exe工具打包Python原始碼,針對我打包過程中遇到的問題,給出解決辦法.

使用py2exe打包需要寫一個Python的指令碼檔案:

setup.py

#coding=utf-8
from 
distutils.core import setup import py2exe import glob # libRootPath = r'D:\ProgramStudy\python278' data_files = ["E:\python_p\logo.ico", (r'mpl-data', glob.glob(libRootPath+r'\Lib\site-packages\matplotlib\mpl-data\*.*')), (r'mpl-data', [libRootPath+r'\Lib\site-packages\matplotlib\mpl-data\matplotlibrc'
]), (r'mpl-data\images', glob.glob(libRootPath+r'\Lib\site-packages\matplotlib\mpl-data\images\*.*')), (r'mpl-data\fonts', glob.glob(libRootPath+r'\Lib\site-packages\matplotlib\mpl-data\fonts\*.*'))] setup( windows=[ { "script":'study_main.py', "icon_resources":[(1, "logo.ico"
)] }], options = { 'py2exe': { 'dll_excludes':['MSVCP90.dll', 'numpy-atlas.dll'], "includes": ["matplotlib.backends", "matplotlib.figure", "pylab", "numpy", "matplotlib.backends.backend_tkagg"], 'excludes': ['_gtkagg', '_tkagg', '_agg2', '_cairo', '_cocoaagg', '_fltkagg', '_gtk', '_gtkcairo', ] } }, data_files=data_files )


【說明】

(1)需要安裝py2exe的Python庫,可以使用pip install安裝工具,也可以在官網下載安裝;

(2)由於打包的過程會需要很多dll動態連結庫檔案,以及lib檔案,需要我們在data_file中指定這些檔案的位置,是在你電腦中Python安裝目錄下,由於我的專案中使用到了matplotlib來畫圖,所以會用到Python/Lib下matplotlib的lib和dll檔案;

(3)第8行,指定了專案的logo所在的位置,需要時ico格式的圖片,win7上logo無法正常顯示,需要下載Greenfish Icon Editor Pro軟體對你的icon檔案進行處理,處理方法網上有;

(4)第17行,指定專案的入口檔案,無論專案的檔案有多少個,此處只需要指定入口的那個檔案,就是有:

if __name__ == "__main__":
    main()

的檔案;

(5)第23行,使用py2exe打包可能會有下面的錯誤:

此時就需要加第23行的這一句,本專案中使用matplotlib畫圖,而matplotlib是依賴numpy庫的,同時可能會報numpy-atlas.dll no such file的錯誤,同樣可以新增。 (6)numpy-atlas.dll的缺失,會導致程式打包正常,但點選打包之後的exe沒有任何反應,可能失去少某些dll動態連結庫檔案,numpy-atlas.dll庫檔案在python安裝目錄下,搜尋一下就找到了,另外,要是exe可執行檔案點選之後沒有反應,可以將其拖拽到cmd命令列中執行,會打印出出現的錯誤。 完成了上面的指令碼檔案之後,在命令列中執行打包操作:
python setup.py py2exe
就開始自動打包。 【注意】上面setup.py檔案就是上面編寫的打包指令碼。 【其他需要說明的】 (1)相容性: 不同的系統上檔案系統的路徑表示的格式是不太相同的,比如我們專案的用到的圖片都放在專案根目錄下的icon資料夾下,一種不太正確的路徑定位方式:
import os.path

main_dir = os.path.split(os.path.abspath(__file__))[0]
iconRootPath = main_dir+os.sep+"icon"
正確的定位方式:
import os.path

iconRootPath = os.getcwdu()+os.sep+"icon"
os.getcwdu() 指向了當前專案,也就是打包後exe可執行檔案所在的目錄,一般不要使用斜槓或者反斜槓作為分隔符,而是使用os.sep。 (2)專案結構 使用py2exe打包之後的資料夾中除了一大堆dll,lib檔案之外,可以找到那個exe可執行檔案,但我們點選之後,回報各種資原始檔找不到,加入我們在專案中使用了圖片,那麼需要把圖片資料夾額外拷貝到專案目錄下,資料庫檔案等等,py2exe打包過程是不會把這些資原始檔打包進來的,需要手動拷貝進來:
(3)sRGB警告 在win7系統中,微軟提高了對圖片質量的檢測,專案中的圖片可能會彈出下面的警告框:

"iccp known incorrect sRGB profile" 警告

這不是錯誤,但為了提高使用者的體驗,需要將這個框 去除,可以使用ImageMagick對圖片進行轉換,其實是該軟體中magick.exe這個工具進行圖片轉換的:
e.g. 使用magick.exe對D盤下的logo_sys.png進行轉換,在cmd中執行:
magick.exe D:\logo_sys.png D:\logo_sys.png
下面的程式可以批量處理資料夾下所有的圖片檔案:
import os
# rootPath是需要轉換的圖片所在的根目錄
rootPath = "D:/icon"
# magick.exe所在的路徑
commandTool = os.getcwdu()+os.sep+"tools"+os.sep+'magick.exe'
# 獲得rootPath目錄下所有圖片檔案的全路徑
def FindExamAllFiles():
    tmp = []
    for root, dirs, files in os.walk(rootPath):
        for filepath in files:
            imgFileFullPath = os.path.join(root, filepath)
            if imgFileFullPath.endswith('.png'):
                tmp.append(imgFileFullPath)
    return tmp

if __name__ == "__main__":pngPathList = FindExamAllFiles()
    for pngPath in pngPathList:
        # 拼湊cmd命令
command = "{0} {1} {2}".format(commandTool, pngPath, pngPath)
        os.system(command)

要是我們的應用會涉及到使用者自主匯入圖片的操作,為了保證不彈出sRGB警告框,可以在每次讀入圖片檔案之後,呼叫下面的函式,首先對圖片進行sRGB處理:
import platform
# 處理資料夾中單個的圖片
def convertsRGBImageFromTmp(iconFullPath):
    winVerName = platform.win32_ver()[0]
    if winVerName != None and winVerName.upper() == 'XP':
        return
    else:
        command = "{0} {1} {2}".format(commandTool, iconFullPath, iconFullPath)
        try:
            os.system(command)
        except:
            pass
    pass
因為sRGB的檢測是在win7以及之後版本的系統上才有的,在XP的系統上是無需進行該操作的,Python提供了platform這個庫來檢測當前系統的版本,我們可以使用platform.win32_ver()[0]獲得版本的名稱,並進行不同的操作。 (4)許可權說明 正常情況下,windows系統允許你的應用從其他的路徑下讀取檔案,但是一般不允許應用在 除應用根目錄及以下的其他目錄中寫內容,即,你可以讀取windows上大多數檔案系統中的檔案,只允許往os.getcwdu()目錄下寫內容,其他路徑是不允許寫操作的。