当前位置: 首页 > news >正文

pyinstall 打包基于PyQt5和PaddleOCR的项目为.exe

简介: 

最近做了一个小项目,是基于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报错,大概率就是有项目需要的库没有打包进来。所以我们百度百度,是什么包没有导入,我们手动复制进去就好了。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • phpinfo
  • ubuntu24.04 linux bcm94352hmb 无线网卡(带蓝牙功能)无法连接蓝牙设备的解决办法
  • LINUX多进程相关
  • Hadoop3:HDFS存储优化之小文件归档
  • XML 编辑器:功能、选择与使用技巧
  • 北斗高精度服务:无人驾驶领域的创新引擎
  • 基于opencv的图片加水印实现方案
  • ubuntu 通讯学习笔记
  • GESP CCF C++ 三级认证真题 2024年6月
  • 常用的设计模式有哪些
  • List数据的几种数据输出方式
  • Qt中 .pro、.pri、.prf、.prl文件简解
  • LG 选择 Flutter 来增强其智能电视操作系统 webOS
  • winform 去掉Chart左侧空白
  • 智慧水利:迈向水资源管理的新时代,结合物联网、云计算等先进技术,阐述智慧水利解决方案在提升水灾害防控能力、优化水资源配置中的关键作用
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 03Go 类型总结
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Centos6.8 使用rpm安装mysql5.7
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript实现分页效果
  • maven工程打包jar以及java jar命令的classpath使用
  • mongodb--安装和初步使用教程
  • vue2.0项目引入element-ui
  • windows下使用nginx调试简介
  • 经典排序算法及其 Java 实现
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 深入浏览器事件循环的本质
  • 使用common-codec进行md5加密
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 微信小程序开发问题汇总
  • 移动端唤起键盘时取消position:fixed定位
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • ​ArcGIS Pro 如何批量删除字段
  • #Datawhale AI夏令营第4期#多模态大模型复盘
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (1)Android开发优化---------UI优化
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (42)STM32——LCD显示屏实验笔记
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (黑马C++)L06 重载与继承
  • (一)基于IDEA的JAVA基础10
  • .Net Core 笔试1
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net MVC中使用angularJs刷新页面数据列表
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NetCore项目nginx发布
  • .Net实现SCrypt Hash加密
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @NotNull、@NotEmpty 和 @NotBlank 区别