wxPython开发总结---将Python源代码打包成exe可执行文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tianmaxingkong_/article/details/54318224

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打包可能会有下面的错误:

Error: “MSVCP90.dll: No such file or directory”

此时就需要加第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()目录下写内容,其他路径是不允许写操作的。

猜你喜欢

转载自blog.csdn.net/tianmaxingkong_/article/details/54318224