上一篇文章创建了项目后,本章我们进行项目的打包工作。
本项目的所有演示代码:github可在这里下载。
打包只用的工具为PyInstaller

1 准备环境

1.1 安装PyInstaller

首先检查本机有没有安装PyInstaller ,如果没有安装的话,需要运行

	pip3 install PyInstaller

或者

	pip install PyInstaller

根据自己机器的环境而定。

2.初始化虚拟安装环境

创建虚拟环境的目的是为了保持打包环境的干净,避免引入其他的无关的库,导致包过大,或者打包出来的exe不能运行的问题。
不是必须,但是强烈建议。

总共三个命令在terminal运行。

2.1 创建虚拟环境

该命令会创建一个新的干净的文件夹(没有任何三方的依赖库),用于后面python的环境调用。
注意这里python -m venv packenv 或者 python3 -m venv packenv的区别,要看自己电脑的默认python版本而定。

	python -m venv packenv

2.2 加载虚拟环境

加载上面创建的虚拟路径的脚本

	call packenv\scripts\activate.bat

运行后会发现下图绿色的框内的文字,说明虚拟环境进入成功
在这里插入图片描述

2.3 添加依赖库

如果项目没有引入其他三方库,就只需要调用如下脚本。我们的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.

3 开始打包

3.1 进入到我们工程的路径

cd C:\Users\Administrator\Documents\PyDemo

3.2 打包尝试

可以通过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.specpyinstaller自动生成的配置文件,后续修改打包配置都可以直接在上面修改。后面会做具体介绍。

好了,我们现在尝试运行dist\pymain\pymain.exe的exe文件,不出意料的出错了。
在这里插入图片描述
原因是我们的.ui文件找不到,没有包含到包里面,所以报错。

3.3 解决ui文件报错

解决ui文件报错的方法至少有三种,任选一种就行,个人推荐第三种

3.3.1 方法一:手动拷贝

手动将.\formmain.ui目录下的的文件,拷贝到dist\pymain\formmain.ui1
重新运行,exe,成功。

3.3.2 方法二:修改打包命令

我们通过 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;."

3.3.3 方法三:修改.spec文件

首先我们先要了解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,也成功。

4 小结

上诉三种拷贝方法,都行,但是推介用spec的方式。因为spec的内容直观且容易修改。

但是我们发现,打包的exe大小居然高达98.5 MB,太大了。
下节我们讨论如何瘦身。~~

其他章节:
Pyside2 学习系列一:创建包含ui文件的项目 (超详细的Pyside2 攻略)
Pyside2 学习系列二:PyInstaller打包项目exe (超详细的Pyside2 攻略)
Pyside2 学习系列三:PyInstaller打包项目瘦身(超详细的Pyside2 攻略)

参考链接:blog
官方链接:点这里

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐