1、pyinstaller使用

PyInstaller命令行选项可以通过帮助信息查看:
pyinstaller --help

-y | --noconfirm:直接覆盖输出文件,而无需提示,在多次重复运行命令时可避免反复确认。
-D | --onedir:生成包含执行文件的目录(默认行为)。
-F | --onefile:生成单一的可执行文件,不推荐使用。
-i | --icon [.ico | .exe | .icns]:为 Windows/Mac 平台的执行文件指定图标。
--version-file [filename]:添加文件版本信息。
-c | --console | --nowindowed:通过控制台窗口运行程序 并且分配标准输入/输出,(默认行为)。
-w | --windowed | --noconsole:不创建控制台窗口,也不分配标准输入/输出,主要用来运行 GUI 程序。没有输入输出会给调试带来一定困难,因此即便是 GUI 程序,建议在调试时禁用本选项,在最终发布时再打开。

2、PyInstaller规格文件

PyInstaller 在生成文件的同时会创建一个相应的.spec 文件,.spec 文件本质上是一个特殊的 Python 脚本,记录了生成所需的指令。

使用pyinstaller [options] xxx.py进行打包时,PyInstaller 会首先根据选项生成对应的 .spec 文件,然后执行 .spec 文件所指定的过程生成最终文件。因此,可以直接指定spec文件执行打包过程。

单目录模式生成的spec 文件格式如下:

1
2
3
4
a = Analysis(...)
pyz = PYZ(...)
exe = EXE(...)
coll = COLLECT(...)

单文件模式生成的spec 文件格式如下:

1
2
3
a = Analysis(...)
pyz = PYZ(...)
exe = EXE(...)

可以将指定文件和指定目录打包进行打包,如下:

1
2
3
4
a = Analysis(...,
datas=[('config.ini', '.'),
('modelsAndFiles', 'modelsAndFiles')],
...)

将config.ini文件打包当可执行文件当前目录下,将modelsAndFiles目录打包到可执行文件当前目录下。

3、PyInstaller 打包遇到问题

1、在命令行中,使用pyinstaller -D fun1.spec命令

生成build,dist目录,进入./dist/fun1目录后,运行fun1.exe

出现如下

FileNotFoundError:’Counld not find module:caffe2_detectron_ops.dll‘:

可以使用pyi-bindepend查看caffe2_detectron_ops.dll的依赖

由于我没有配置环境变量,我直接知道pyi-bindepend.exe所在的文件,在此目录直接运行

逐个依赖查看,发现缺少libiomp5md.dll

解决方法:

libiomp5md.dll复制到./dist/fun1目录即可解决。

注意:只有Python3.8版本,打包才出现,我用Python3.7没出现这个问题。

2、将缺少的包导入后,可以运行exe,但是当点击人脸识别后,报错:

解决方法:

更换pytorch和torchvision的版本

最终更换为

1
2
pytorch==1.2.0
torchvision==0.4.0

其他版本pytorch下载链接

离线安装命令

1
2
3
4
conda install --offline -n envs_name xxx.tar.bz2

envs_name:环境名
xxx.tar.bz2:下载的包

3、更换pytorch和torchvision版本后,报错:

1
ModuleNotFoundError: No module named 'numpy.random.common'

解决方法:

在打包生成的spec文件中,在hiddenimports参数中添加如下内容:

1
hiddenimports=['numpy.random.common','numpy.random.bounded_integers','numpy.random.entropy']

4、点击采集人像后,出现错误

numpy版本降低为1.17.0后,出现这个read-only错误。

一般是你读取的图片的时候,默认选择的是”r”,”rb”模式有关。

原本代码为:

1
qimg = qimage2ndarray.array2qimage(np.asarray(img))

修正的办法: 手动修改图片的读取状态:

1
2
3
img1 = np.asarray(img)
img1.flags.writeable = True # 将数组改为读写模式
qimg = qimage2ndarray.array2qimage(img1)

修改后报错:

cannot set WRITABLE flag to True of this array

百度查博客,发现解决方法:

1
2
3
img1 = np.asarray(img)
img1 = np.require(img, dtype='f4', requirements=['O', 'W'])
qimg = qimage2ndarray.array2qimage(img1)

5、在其他人电脑上运行出错

解决方法:

出现此错误的原因是缺少了ssl证书,因此可以从Python官网上下载相应python版本的压缩包,解压后将解压包中的_ssl.pyd复制到Anaconda/envs目录下相应的环境中的DLLs下覆盖原文件,

将解压包中的libcrypto-1_1.dll、libssl-1_1.dll复制到Anaconda/envs目录下相应的环境的根目录即可解决问题。