继上一篇文章创建了项目后,本章我们进行项目的打包工作。
本项目的所有演示代码:github可在这里下载。
打包只用的工具为PyInstaller
。
PyInstaller
首先检查本机有没有安装PyInstaller
,如果没有安装的话,需要运行
pip3 install PyInstaller
或者
pip install PyInstaller
根据自己机器的环境而定。
创建虚拟环境的目的是为了保持打包环境的干净,避免引入其他的无关的库,导致包过大,或者打包出来的exe不能运行的问题。
不是必须,但是强烈建议。
总共三个命令在terminal运行。
该命令会创建一个新的干净的文件夹(没有任何三方的依赖库),用于后面python的环境调用。
注意这里python -m venv packenv
或者 python3 -m venv packenv
的区别,要看自己电脑的默认python版本而定。
python -m venv packenv
加载上面创建的虚拟路径的脚本
call packenv\scripts\activate.bat
如果项目没有引入其他三方库,就只需要调用如下脚本。我们的demo项目就运行这个就够了。
pip3 install PySide2 PyInstaller
如果项目导入了其他三方依赖库,也需要再次安装一次,因为这里是干净的环境,比如 项目中from selenium import webdriver
导入了selenium
库,就需要再次运行 pip3 install selenium
安装, 或者 pip3 install PySide2 PyInstaller selenium
一起安装。
(packenv) C:\Users\Administrator>pip3 install PySide2 PyInstaller
Requirement already satisfied: PySide2 in c:\users\administrator\packenv\lib\site-packages (5.15.2)
Requirement already satisfied: PyInstaller in c:\users\administrator\packenv\lib\site-packages (4.5.1)
Requirement already satisfied: shiboken2==5.15.2 in c:\users\administrator\packenv\lib\site-packages (from PySide2) (5.15.2)
Requirement already satisfied: pefile>=2017.8.1; sys_platform == "win32" in c:\users\administrator\packenv\lib\site-packages (from PyInstaller) (2021.5.24)
Requirement already satisfied: pyinstaller-hooks-contrib>=2020.6 in c:\users\administrator\packenv\lib\site-packages (from PyInstaller) (2021.3)
Requirement already satisfied: altgraph in c:\users\administrator\packenv\lib\site-packages (from PyInstaller) (0.17)
Requirement already satisfied: setuptools in c:\users\administrator\packenv\lib\site-packages (from PyInstaller) (39.0.1)
Requirement already satisfied: pywin32-ctypes>=0.2.0; sys_platform == "win32" in c:\users\administrator\packenv\lib\site-packages (from PyInstaller) (0.2.0)
Requirement already satisfied: importlib-metadata; python_version < "3.8" in c:\users\administrator\packenv\lib\site-packages (from PyInstaller) (4.8.1)
Requirement already satisfied: future in c:\users\administrator\packenv\lib\site-packages (from pefile>=2017.8.1; sys_platform == "win32"->PyInstaller) (0.18.2)
Requirement already satisfied: typing-extensions>=3.6.4; python_version < "3.8" in c:\users\administrator\packenv\lib\site-packages (from importlib-metadata; python_version < "3.8"->PyInstaller) (3.10.0.2)
Requirement already satisfied: zipp>=0.5 in c:\users\administrator\packenv\lib\site-packages (from importlib-metadata; python_version < "3.8"->PyInstaller) (3.5.0)
You are using pip version 10.0.1, however version 21.2.4 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
cd C:\Users\Administrator\Documents\PyDemo
可以通过pyinstaller -h
查看命令帮助
这里我们直接运行
pyinstaller -w pymain.py
因为 pyinstaller
默认打包是控制台程序,我们这里加上-w
的命令是说明我们是windows桌面程序,说明如下 -w, --windowed, --noconsole Windows and Mac OS X: do not provide a console window for standard i/o. On Mac OS X this also triggers building an OS X .app bundle. On Windows this option will be set if the first script is a '.pyw' file. This option is ignored in *NIX systems.
运行结果:
(packenv) C:\Users\Administrator\Documents\PyDemo>pyinstaller -w pymain.py
73 INFO: PyInstaller: 4.5.1
74 INFO: Python: 3.6.7
74 INFO: Platform: Windows-10-10.0.19041-SP0
77 INFO: wrote C:\Users\Administrator\Documents\PyDemo\pymain.spec
81 INFO: UPX is not available.
84 INFO: Extending PYTHONPATH with paths
['C:\\Users\\Administrator\\Documents\\PyDemo',
'C:\\Users\\Administrator\\Documents\\PyDemo']
........ 省略部分
7286 INFO: Building COLLECT because COLLECT-00.toc is non existent
7290 INFO: Building COLLECT COLLECT-00.toc
8383 INFO: Building COLLECT COLLECT-00.toc completed successfully.
说明打包成功,然后我们切到目录下面去,发现多了几个文件。
.
├── pymain.py
├── formmain.ui
├── pymain.pyproject
├── pymain.pyproject.user
├── pymain.spec
├── build
│ └── pymain
│ ├── Analysis-00.toc
│ ├── COLLECT-00.toc
│ ├── EXE-00.toc
│ ├── PKG-00.pkg
│ ├── PKG-00.toc
│ ├── PYZ-00.pyz
│ ├── PYZ-00.toc
│ ├── pymain.exe
│ ├── pymain.exe.manifest
│ ├── base_library.zip
│ ├── warn-pymain.txt
│ └── xref-pymain.html
└── dist
└── pymain
├── MSVCP140.dll
├── PySide2
├── pymain.exe
├── pymain.exe.manifest
├── Qt5Core.dll
...
build\
和 dist\
和 pymain.spec
是多出来的打包生成的文件。
build
我们不需要使用,可以忽略掉。dist\
路径包含了我们生的的exe和各种依赖文件, 可以直接拿去发布。pymain.spec
是pyinstaller
自动生成的配置文件,后续修改打包配置都可以直接在上面修改。后面会做具体介绍。好了,我们现在尝试运行dist\pymain\pymain.exe
的exe文件,不出意料的出错了。
原因是我们的.ui文件找不到,没有包含到包里面,所以报错。
解决ui文件报错的方法至少有三种,任选一种就行,个人推荐第三种
手动将.\formmain.ui
目录下的的文件,拷贝到dist\pymain\formmain.ui1
重新运行,exe,成功。
我们通过 pyinstaller -h
可以看到,有这么个命令--add-data
--add-data <SRC;DEST or SRC:DEST>
Additional non-binary files or folders to be added to
the executable. The path separator is platform
specific, ``os.pathsep`` (which is ``;`` on Windows
and ``:`` on most unix systems) is used. This option
can be used multiple times.
可以帮我们自动拷贝过去。
然后我们修改我们的打包命令再次重试。
pyinstaller -w pymain.py --add-data="formmain.ui;."
cmd:
(packenv) C:\Users\Administrator\Documents\PyDemo>pyinstaller -w pymain.py --add-data="formmain.ui;."
73 INFO: PyInstaller: 4.5.1
73 INFO: Python: 3.6.7
75 INFO: Platform: Windows-10-10.0.19041-SP0
84 INFO: wrote C:\Users\Administrator\Documents\PyDemo\pymain.spec
88 INFO: UPX is not available.
93 INFO: Extending PYTHONPATH with paths
['C:\\Users\\Administrator\\Documents\\PyDemo',
'C:\\Users\\Administrator\\Documents\\PyDemo']
373 INFO: checking Analysis
393 INFO: Appending 'datas' from .spec
395 INFO: checking PYZ
406 INFO: checking PKG
407 INFO: Bootloader c:\users\administrator\packenv\lib\site-packages\PyInstaller\bootloader\Windows-64bit\runw.exe
407 INFO: checking EXE
409 INFO: checking COLLECT
WARNING: The output directory "C:\Users\Administrator\Documents\PyDemo\dist\pymain" and ALL ITS CONTENTS will be REMOVED! Continue? (y/N)y
On your own risk, you can use the option `--noconfirm` to get rid of this question.
2520 INFO: Removing dir C:\Users\Administrator\Documents\PyDemo\dist\pymain
2590 INFO: Building COLLECT COLLECT-00.toc
3239 INFO: Building COLLECT COLLECT-00.toc completed successfully.
检查确定ui文件被拷贝到了exe同级目录,exe也运行成功。
注: 这里--add-data
可以多次添加,如果有多个ui文件或者其他资源文件,可以添加多个,然后一起拷贝过去,比如
pyinstaller -w pymain.py --add-data="formmain.ui;." --add-data="formmain2.ui;." --add-data="demo.jpg;."
首先我们先要了解spec文件,相当于pyinstaller 运行后生成的配置文件。也就是说只要配置文件生成后,我们直接修改配置文件,然后重新运行配置文件就可以了。具体官方介绍戳这里
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['pymain.py'],
pathex=['C:\\Users\\Administrator\\Documents\\PyDemo'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='pymain',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='pymain')
datas=
就相当于3.3.2章节里面的--add-data=
参数console=False
就相当于命令行的 -w
参数name=
可以设置打包的exe的名字在这里我们只需要修改 datas=
就行了。
a = Analysis(['pymain.py'],
pathex=['C:\\Users\\Administrator\\Documents\\PyDemo'],
binaries=[],
datas=[('formmain.ui', '.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
或者,有多个资源文件也可以修改成这样
a = Analysis(['pymain.py'],
pathex=['C:\\Users\\Administrator\\Documents\\PyDemo'],
binaries=[],
datas=[
('formmain.ui', '.'),
('formmain2.ui', '.'),
('demo.jpg', '.')
],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
修改保存好了,直接运行命令:pyinstaller pymain.spec
(packenv) C:\Users\Administrator\Documents\PyDemo>pyinstaller pymain.spec
75 INFO: PyInstaller: 4.5.1
76 INFO: Python: 3.6.7
80 INFO: Platform: Windows-10-10.0.19041-SP0
84 INFO: UPX is not available.
85 INFO: Extending PYTHONPATH with paths
['C:\\Users\\Administrator\\Documents\\PyDemo',
'C:\\Users\\Administrator\\Documents\\PyDemo']
.....
WARNING: The output directory "C:\Users\Administrator\Documents\PyDemo\dist\pymain" and ALL ITS CONTENTS will be REMOVED! Continue? (y/N)y
On your own risk, you can use the option `--noconfirm` to get rid of this question.
9081 INFO: Removing dir C:\Users\Administrator\Documents\PyDemo\dist\pymain
9158 INFO: Building COLLECT COLLECT-00.toc
9813 INFO: Building COLLECT COLLECT-00.toc completed successfully.
运行exe,也成功。
上诉三种拷贝方法,都行,但是推介用spec的方式。因为spec的内容直观且容易修改。
但是我们发现,打包的exe大小居然高达98.5 MB
,太大了。
下节我们讨论如何瘦身。~~
其他章节:
Pyside2 学习系列一:创建包含ui文件的项目 (超详细的Pyside2 攻略)
Pyside2 学习系列二:PyInstaller打包项目exe (超详细的Pyside2 攻略)
Pyside2 学习系列三:PyInstaller打包项目瘦身(超详细的Pyside2 攻略)
参考链接:blog
官方链接:点这里