简介:
最近做了一个小项目,是基于PyQt5和PaddleOCR的。需要将其打包为.exe,然后打包过程中遇到了很多问题,也看了很多教程,方法千奇百怪的,最后也是一步一步给试出来了。记录一下,防止以后忘记了。
项目版本:
python: 3.8
PyQt5 :5.15.10
paddleocr :2.8.0
paddlepaddle :2.6.1
opencv-python :4.10.0.84
项目组成:
其中:
1、ppocr、ppstructure、tools为ocr的依赖文件夹
2、ui 为主要是系统ui的文件,组成如下图:
3、mainPage.py是项目的启动文件
4、paddleocr.py是ocr的依赖文件
5、mainPage.spec是生成出来用于打包的文件
具体步骤:
1、安装pyinstaller
进入虚拟环境然后安装打包库
pip install pyinstaller
2、生成spec文件
spec的名字和项目启动文件的名字一样即可
pyinstaller your_spec.spec
3、编辑spec文件
spec文件长这样:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['mainPage.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='mainPage',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='mainPage',
)
1、将项目虚拟环境的第三方库路径填写到pathex里
我的路径是这个:D:\Anaconda\envs\myenv\Lib\site-packages
2、将paddle的依赖包路径写入pathex里
我的路径是这样的:D:\Anaconda\envs\myenv\Lib\site-packages\paddle\libs
3、将paddle的依赖包路径写入binaries中
写好的spec是这样的:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['mainPage.py'],
pathex=['ui\\main_page.py',
'D:\Anaconda\envs\myenv\Lib\site-packages',
'D:\Anaconda\envs\myenv\Lib\site-packages\paddle\libs'],
binaries=[('D:\Anaconda\envs\myenv\Lib\site-packages\paddle\libs','.')],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='mainPage',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='mainPage',
)
然后我们就可以进行打包了
4、打包项目
输入命令进行打包:
pyinstaller mainPage.spec
不出意外打包就欧克了。
当然我打包的时候遇到了一个问题:
A RecursionError (maximum recursion depth exceeded) occurred. For working around please follow these instructions1. In your program's .spec file add this line near the top:: import sys ; sys.setrecursionlimit(sys.getrecursionlimit() * 5) 2. Build your program by running PyInstaller with the .spec file as argument:: pyinstaller myprog.spec 3. If this fails, you most probably hit an endless recursion in PyInstaller. Please try to track this down has far as possible, create a minimal example so we can reproduce and open an issue at https://github.com/pyinstaller/pyinstaller/issues following the instructions in the issue template. Many thanks. Explanation: Python's stack-limit is a safety-belt against endless recursion, eating up memory. PyInstaller imports modules recursively. If the structure how modules are imported within your program is awkward, this leads to the nesting being too deep and hitting Python's stack-limit. With the default recursion limit (1000), the recursion error occurs at about 115 nested imported, with limit 2000 at about 240, with limit 5000 at about 660.
具体的解决办法就是:
在spec文件的最上面加上:
import sys
sys.setrecursionlimit(100000)
打包完成是这样的:
你会发现项目目录中多了两个文件夹
5、启动项目
大概率,直接启动exe是会报错的。所以为了看清报错的具体内容,我们cd到exe所在的目录小启动它。(exe在dist目录里面)
cd到exe目录下以后,输入mainPage.exe 启动项目。
发现抱错:
百度一下,发现解决办法:
就是这个文件夹
在运行,又报错:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\86195\\Desktop\\20\\dist\\mainPage\\_internal\\tools/__init__.py'
想起我们项目目录中又一个tools目录未导入,那么我们同样将其复制到dist目录下
运行exe,ok运行成功!!!
总结
如果打包没问题,运行exe报错,大概率就是有项目需要的库没有打包进来。所以我们百度百度,是什么包没有导入,我们手动复制进去就好了。