目的:将python项目打包成exe文件。
项目特点:该python项目包含多个子文件夹及py文件,与外部有xml数据交换。
使用的库:pyqt5,numpy,matplotlib,opencv-python,scikit-learn
方法:新建虚拟环境,使用pyinstaller
进行打包,避免在anaconda环境下打包体积过大。
问题:anaconda下打包的exe文件约200Mb,新建环境后体积有减小,但是仍然有100Mb。下一步尝试使用UPX
压缩、在visual studio下用C++封装后打包、用python-embedded…
1、新建virtualenv环境,并激活环境
由于anaconda会自带很多不需要用的库,所以直接在开发的环境下打包会导致打包之后的exe文件体积过大,因此在cmd下用系统自带的python新建虚拟环境,只安装必须的库。
1)在cmd窗口下,输入python
,如下图,确定python版本与开发环境是一致的。
Tips:
- 如果安装了python,提示指令出错,将python.exe所在的目录加入系统环境变量中;
- 如果显示的是anaconda的python,可以将anaconda所在的环境变量删掉,或者将官方版python在环境变量中的位置放在anaconda之前;
2)在cmd下,安装virtualenv用于创建独立的python环境;
pip install virtualenv
3)cd
选择一个路径,在该路径下建立新的、干净的python环境;
virtualenv your_env # your_env 自行命名
4)cd
切换到新建环境中的scripts路径下(eg. E:\your_env\Scripts
),输入activate
激活环境;
5)cd
切换到程序目录,该目录下有程序的入口,比如main.py
2、结合pyinstaller,安装必要的库
1)使用pip安装项目中使用到的库;
pip install pyqt5 numpy matplotlib opencv-python scikit-learn
2)使用pyinstaller尝试打包,记下显式缺少的库(eg. ModuleNotFoundError
),再通过pip安装;
pyinstaller -F main.py
比如出现如下信息:
ModuleNotFoundError: No module named 'win32com'
,经查询,是由于缺少pywin32
库。直接通过
pip install pywin32
安装即可。
3)如果执行成功,当前路径下将会多出3个文件:./build
、./dist
、main.spec
3、修改.spec
文件,加入缺失的dll、module
1)cd
切换到dist路径下,运行main.exe
,对于简单的项目,这一步可能直接成功运行,则到此为止。若运行不成功,会出现错误提示,根据提示继续下一步;
2)如果提示....PyInstallerImportError: Failed to load dynlib/dll...
,则找到该dll文件,放在当前程序文件夹中,将main.spec
的datas
修改如下:
# 例子, 第一个引号表示dll名,第二个引号表示路径
datas=[('vcomp140.dll','.'),('MvCameraControl.dll','.')],
3)如果提示ModuleNotFoundError: No module named 'sklearn.utils._cython_blas'
,由于这是在sklearn中的子模块,不能通过pip安装,需要将main.spec
中的hiddenimports
修改如下:
hiddenimports=['sklearn.utils._cython_blas'],
4)修改之后重新编译,需要先将./build
和./dist
文件夹删掉,再用pyinstaller指令,指令中的main.py
改成main.spec
。
pyinstaller -F main.spec
4、将依赖数据(比如用于持久化的数据./data
)和main.exe
放在一个文件夹下,即可运行。
debug:
ModuleNotFoundError: No module named 'pkg_resources.py2_warn'
setuptools
的版本。Tips:
设置国内镜像,提升pip下载速度
在环境变量Home
对应的文件夹中新建一个./pip/pip.ini
文件,加入如下内容:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=mirrors.aliyun.com