打包工具选择
我自己用PyQT5写了一个应用程序,基本上都写好了,到了打包发布这个环节,我知道的有两个工具可以帮我打包分别是
Pyinstaller Cythonpyinstaller会给我打包成一个exe文件,把python解释器、所有依赖包、各种DLL都打包在里面,然后最终出来一个exe文件,听上去是很好。 Cython会给打包成pyd文件,然后依靠包导入的方式完成启动,不会生成exe文件,听上去没有pyinstaller好 两个工具的安装都十分方便快捷:
pip install pyinstaller pip install Cython这两个我都测试了,最终我选择用Cython完成了打包发布。为什么不用pyinstaller,打包出来的exe文件比较大,然后各种命令行操作我也不太熟悉,已经学废了。然后打包完成之后各种DLL无法load跟找不到,时间不等人啊!最重要的,pyinstaller打包完成exe其实就是一个压缩包,特别容易被反编译跟逆向工程取得源码!谁让我已经用过这招,所以我猜别人也会用。 选择Cython是转C然后编译生成的,想要逆向是十分困难,源码保护会好点,另外Cython打包只要一个脚本运行一下就好啦,这个脚本还是我从网上的来的,感谢这个脚本作者!脚本随便改了改,就可以直接使用了。
打包流程与目录结构
在开始打包之前,先把一些非源码的文件整理好,放在项目的资源文件夹下面,我有两个资源文件夹分别是images跟models,它们就不用打包了。然后我把我的五个源码文件夹
以dlcore为例,修改脚本,运行package_installer,脚本我也贴出来,有需求的自取,放到跟项目同层目录下面,会自动创建build文件夹的。
importsys,os,shutil,time fromdistutils.coreimportsetup fromCython.Buildimportcythonize start_time=time.time() curr_dir=os.path.abspath('.') parent_path=sys.argv[1]iflen(sys.argv)>1else"" setup_file=__file__.replace('/','\') build_dir="build" build_tmp_dir=build_dir+"/temp" s="#cython:language_level=3" defget_py(base_path=os.path.abspath('.'),parent_path='',name='ui',excepts=(),copyOther=False,delC=False): """ 获取py文件的路径 :parambase_path:根路径 :paramparent_path:父路径 :paramexcepts:排除文件 py文件的迭代器 """ full_path=os.path.join(base_path,parent_path,name) forfilenameinos.listdir(full_path): full_filename=os.path.join(full_path,filename) ifos.path.isdir(full_filename)andfilename!=build_dirandnotfilename.startswith('.'): forfinget_py(base_path,os.path.join(parent_path,name),filename,excepts,copyOther,delC): yieldf elifos.path.isfile(full_filename): ext=os.path.splitext(filename)[1] ifext==".c": ifdelCandos.stat(full_filename).st_mtime>start_time: os.remove(full_filename) eliffull_filenamenotinexceptsandos.path.splitext(filename)[1]notin('.pyc','.pyx'): ifos.path.splitext(filename)[1]in('.py','.pyx')andnotfilename.startswith('__'): path=os.path.join(parent_path,name,filename) yieldpath else: pass defpack_pyd(): #获取py列表 module_list=list(get_py(base_path=curr_dir,parent_path=parent_path,excepts=(setup_file,))) try: setup( ext_modules=cythonize(module_list,compiler_directives={'language_level':"3"}), script_args=["build_ext","-b",build_dir,"-t",build_tmp_dir], ) exceptExceptionasex: print("error!",str(ex)) else: module_list=list(get_py(base_path=curr_dir,parent_path=parent_path,excepts=(setup_file,),copyOther=True)) module_list=list(get_py(base_path=curr_dir,parent_path=parent_path,excepts=(setup_file,),delC=True)) ifos.path.exists(build_tmp_dir): shutil.rmtree(build_tmp_dir) print("complate!time:",time.time()-start_time,'s') defdelete_c(path='.',excepts=(setup_file,)): ''' 删除编译过程中生成的.c文件 :parampath: :paramexcepts: ''' dirs=os.listdir(path) fordirindirs: new_dir=os.path.join(path,dir) ifos.path.isfile(new_dir): ext=os.path.splitext(new_dir)[1] ifext=='.c': os.remove(new_dir) elifos.path.isdir(new_dir): delete_c(new_dir) if__name__=='__main__': try: pack_pyd() exceptExceptionase: print(str(e)) finally: delete_c()最终build文件夹中生成对应的pyd文件如下:
运行完这些源码文件夹把得到pyd文件分别拷贝到另外一个目录下对应文件夹中,最终我的打包好的目录结构如下:
其中requirements.txt里面是需要安装第三方依赖库,在该目录运行命令行即可完成安装:
pip install -r requirements.txt参考readme文件,可以完成OpenVINO2022、TensorRT8.x配置支持。 我手写了一个简单startup.bat文件,双击startup.bat即可运行打包好的应用!
@echo "try to run openvm" SET PYTHONPATH=.%PYTHONPATH% cd ui python application_ui.py
运行截图如下:
遇到的坑
最后说一下,我用cython打包遇到的一个大坑:
我有个超类ImageTask,然后里面定义几个抽象方法,其中一个方法名是exec,谁知道这个是cython无法解析的字符串,我猜可能因为代码安全检测无法通过,所以一直给报截图的错误,后面我把这个方法名称从exec改成t_exec就可以把对应的py文件转pyd文件了。
使用pyinstaller打包时候会遇到
Error: geos_c.dll not found, required by hook-shapely.py
去下载geos_c.dll https://www.dll-files.com/geos_c.dll.html
然后扔到windows/system32里面去就好啦!
-
OpenCV
+关注
关注
31文章
634浏览量
41329 -
python
+关注
关注
56文章
4792浏览量
84613 -
pyqt5
+关注
关注
0文章
25浏览量
3395
原文标题:PyQT5+OpenCV开发的应用如何打包发布?
文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论