使用pyinstaller打包

记录一下使用pyinstaller打包exe的经历,主要参考了这篇知乎:别再问我Python打包成exe了(最适合小白的终极解答)!

前提是得安装好pyinstaller包,这个就不说了

之前打包时的主要问题是pyinstaller会把程序用到的所有第三方包及相关的包都打包进来,以至于程序体积非常大,这次主要学习了一下怎么在虚拟环境里只把程序需要用的包打包进来,减小程序体积。

第一步:创建虚拟环境

需用到以下命令:

conda create -n 虚拟环境名字 python==3.6  #创建虚拟环境
conda activate 虚拟环境名字  #激活虚拟环境
conda deactivate  #退出虚拟环境

我先创建了一个名字叫abc的虚拟环境

使用pyinstaller打包_第1张图片

 第二步:激活虚拟环境

使用pyinstaller打包_第2张图片

激活虚拟环境后命令行变成这样子

然后将目录切换到要打包的python程序目录下:

使用pyinstaller打包_第3张图片

第三步,运行pyinstaller进行打包

 使用pyinstaller打包_第4张图片

这里面的参数解释如下表

我用的这些参数实际上是产生了一个目录用于部署、带窗口的可执行程序、设置了一个icon

使用pyinstaller打包_第5张图片

正常情况下pyinstaller会显示一系列命令,如果最后显示completed successfully就是成功了,如下图所示。

打包成功之后原来目录下就有了build和dist两个文件夹,我们所打包地exe就躺在dist文件夹下的程序名文件夹里。

更新

1.程序需要调用其他exe时打包到一起的方法

参考:Pyinstaller如何将资源文件一起打包至exe中

先上述的方法打包一次,然后修改spec文件,在Analysis的datas中放入所需调用的PDB_tools.exe,PDB_tools.exe运行所依赖的文件、以及程序需要的其他文件(如logo.ico)。这些文件在打包后的exe运行时,会被自动释放到一个临时文件夹中进行调用。

datas的列表中为一系列元组,前面为打包的资源文件,后面是在临时文件中的相对路径,'.'表示在临时文件夹根目录下。

使用pyinstaller打包_第6张图片

通过以下函数可以获知程序运行时产生的临时文件夹的路径:

def resource_path(relative_path):
    if getattr(sys, 'frozen', False): #是否Bundle Resource
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

用这种方法运行时,PDB_tools.exe生成的各种txt文件还是在主程序的目录下,因此不需要从临时文件夹中读入txt,直接在主程序的cwd下读入即可。

2.程序左上角及任务栏logo无法显示问题

参考:pyinstaller 打包pyqt设置图标 (任务栏图标),解决打包后到其他文件夹或者电脑找不到图标问题【亲测可用】

也是用的上述的将资源包一起打包的方法,将logo.ico一起打包进去。然后设置icon的时候引用改为临时文件的路径即可,此时就用到了上面那个代码块获取临时路径的方式了。

icon = self.resource_path('logo.ico')
MainWindow.setWindowIcon(QIcon(icon))

3.打包方式改变

采用了spec将资源包全部放进临时文件后,用-F后缀即可将文件打包为一个文件,避免了原来一堆文件的尴尬。简单一行即可完成:

pyinstaller -F genMemberInfo.spec

Bug shoting

当然绝大多数情况下并没有这么顺利,需要来回折腾几下。

1.虚拟环境缺第三方包的问题

首先可能遇到的一个问题是虚拟环境中缺少程序所用到的第三方包,这个好解决,直接在虚拟环境下pip install就行了。举个例子:

 当然更快的是用国内的服务器来安装:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller #清华源
pip install -i https://pypi.douban.com/simple/ pyinstaller #豆瓣源

 2.另外的一些奇奇怪怪的问题

我这个程序里用的是pyqt5做的界面,用pyinstaller打包时报错说C:\Users\Administrator\AppData\Local\pyinstaller\bincache00_py38_64bit\pyqt5路径下找不到QtGui.pyd、Qtcore.pyd等等文件,然后我用everything搜了一下,这些文件明明是安装了的,这就很离谱,最后直接简单粗暴地把这几个pyd拷贝到那个目录里才解决了问题。

 3.另外还有一些问题没有解决(在前面更新已解决)

我写的这个程序有的功能依赖于一些Fortran代码,由于不太懂python和fortran联合编程,就采用调用一个fortran编写的exe,然后再进行接下来的操作的方法。这样一来打包python的时候就需要把fortran生成的这个exe打包进去,目前暂时还没找到方法,于是直接将fortran的exe丢到python打包形成的目录里让它调用了。后面有时间再研究一下这个。

你可能感兴趣的:(pyinstaller,PyQt5,python,pyinstaller)