PyQt5初学试验记录(三):Pyinstaller打包小结

前言:本记录为笔者自学过程中的简单笔记,说明了从安装库到最终打包成.exe的过程,分为三个部分,供初学者参考交流,存在表述有误的部分还请读者们多多指教,下方为第三部分目录。

文章目录

    • 一、Pyinstaller打包流程
    • 二、打包遇到的问题(未完全解决)
      • 1、No moudle named
      • 2、No such file or directory
      • 3、Permission deniede
      • 4、Not enough values to unpack
      • 5、.exe 的图标显示异常
      • 6、杀毒软件误报
      • 7、兼容性
    • 三、关于Pycharm项目的迁移
    • 四、小结

一、Pyinstaller打包流程

笔者之前制作了一个基于 PyQt5 的工具(详见 PyQt5初学试验记录),为了尝试在其他没有 python 相关环境的电脑上运行,需要打包成 .exe文件,搜索了许多资料皆推荐 pyinstaller,理由是好用。但是……实际体验极差TAT,大概是因个人才疏学浅,致使各种小问题迟迟得不到解决,在最终基本满足需求后,还是该写一篇小结回顾一番,Let’s go!

首先安装pyinstaller,在命令行输入指令:

pip install pyinstaller

安装完成显示 successfully 后即可开始打包工作,接下来在命令行输入:

cd /d 盘符:\被打包文件的目录

进入被打包的 xxx.py 文件所在目录,如 e:\filepath,再输入:

pyinstaller -w -D xxx.py

-w 表示打包后的 .exe 不带 Shell 窗口运行,-D 表示打包成目录即文件夹形式,该文件夹中包含一个 .exe 和其他相关文件,一般多目录多文件结构的项目就如此打包,单个 .py 可以用 -F 参数;

打包完成后会在 xxx.py 根目录生成 build 和 dist 两个文件夹,和一个 xxx.spec 文件(用于配置打包细则),生成的 .exe 就在 dist 的子目录下。在确保万无一失之前,建议在命令行中调用而不要直接双击 .exe,这样做在出错的时候程序便不会闪退,可以将错误信息显示在 Shell 中,便于调试。
PyQt5初学试验记录(三):Pyinstaller打包小结_第1张图片

修改好 xxx.spec 后再次执行:

pyinstaller -w -D xxx.spec

二、打包遇到的问题(未完全解决)

下面来看看可能遇到的问题:

1、No moudle named

Pyinstaller 在进行打包的时候会自动搜索 xxx.py 的依赖,但傻瓜式的操作总会有不足之处,它还是有可能找不齐需要的东西,这时候就要用到上述的配置文件 xxx.spec 了,修改该文件的 Analysis 方法如下:

a = Analysis(['MainFunction.py',
              'E:\\NewSysCrawler\\GUI_Call\\MyCrawler.py',
              'E:\\NewSysCrawler\\GUI_Call\\getdetails.py',
              'E:\\NewSysCrawler\\GUI_Call\\getbase.py',
              'E:\\NewSysCrawler\\QtFile\\getXlsxWidget.py',
              'E:\\NewSysCrawler\\QtFile\\mainWidget.py'],
             pathex=['E:\\NewSysCrawler','E:\\NewSysCrawler\\venv\\Lib\\site-packages'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

第一个[ ]中为被打包的 xxx.py (笔者的是 MainFunction.py),在其中继续添加项目中其他 .py 文件的路径,注意分隔符为双斜杠\\。第二个 pathex 中为打包时的搜索路径,将项目依赖的库所在路径添加进去。另外,datas 中为项目中用到的其他文件数据(或第三方.dll),笔者用了其他方法做关联故未填写。如此一来,第一波问题就应该解决了。

2、No such file or directory

程序执行中相关的本地文件(如笔者的爬虫工具需要的 cookie 会从本地 .txt 中载入历史记录),如果在 datas 中没有设置可能会出现该问题,笔者的解决办法是直接把需要的文件(夹)放在生成的 .exe 根目录中,在源码中要注意路径的指定,如 .\Files 为 .exe 根目录下的 Filepath 文件夹, ..\OtherFiles 为 .exe 上级目录中的另一个文件夹;

3、Permission deniede

编辑至此,笔者有点忘了这个错误是在什么情况下产生的了……莫名其妙的就解决了。好像是什么权限不足,推测是笔者的爬虫工具会把爬取的数据输出一个 .txt 到指定目录,但是其所在目录不存在,修改代码创建该目录即可(或者应该也可以在上述 datas 里解决):

result =str(html.text) # 爬虫获取的内容
dirs = '..\\OtherFiles'
if not os.path.exists(dirs): # 判断目录是否存在,不存在则创建
    os.mkdir(dirs) # 
# open无法打开/创建不存在的目录,但可以自动新建.txt 
with open(dirs+"\\"+txt,'a',encoding="utf-8-sig") as file_handle:      
    file_handle.write(result)   # 写入

4、Not enough values to unpack

检查一下 pyinstaller 输入的参数格式;

5、.exe 的图标显示异常

Pyinstaller 最麻烦的问题所在,其对图标的设置有一定的要求且 windows 系统本身对图标也有要求(但是我至今还没摸索出细节……),笔者反复尝试仍然未能达到理想效果,打包时所用参数为:

pyinstaller -w -D xxx.py -i e:\icons\myIcon.ico

Pyinstaller 设置图标只能处理 .ico 文件,用以下代码可以一次性生成各种尺寸的图标文件(或者用 Png2Ico 、格式工厂之类的工具,亦或在图标网站上下载):

from PIL import Image

image_size = [128,64,48,32,16]
def create_icon():
    for size in image_size:
        pri_image = Image.open("Icon.png")
        pri_image.resize((size, size), Image.ANTIALIAS).save("Icon_%d.ico" % (size))

if __name__ == "__main__":
    create_icon()

生成的 .exe 的图标还是不显示(不一定,也可能会成功)!于是笔者改用快捷方式,手动更改图标,但快捷方式在其他电脑就失效了。之后笔者又尝试写了一个启动器,专门用来调用之前生成的 .exe ,代码如下:

import os

def main():
    os.chdir(".\\NewSysCrawler20.4.23") # 更改工作目录
    os.system('NSCrawler.exe') # 执行

if __name__ == "__main__":
    main()

使用 os.system() 会在运行 .exe 同时打开 Shell 窗口,而后改用:

subprocess.call('NSCrawler.exe')

同样用 pyinstaller 打包这个启动器的 .py,并且在打包启动器时设置图标(哇图标成功显示了!),最终变成了用 runNSC.exe 来调用原打包目录下原工具的 NSCrawler.exe 的情况;
PyQt5初学试验记录(三):Pyinstaller打包小结_第2张图片

至此,图标问题勉强解决了(后来发现打包单文件似乎都能成功…)。

另外,推荐一个图标绘制器 Greenfish Icon Editor Pro,想要自己动手设计图案的同学可以尝试一下(笔者的爬虫工具图标一开始是用 sai 瞎画的一个爪子)。

6、杀毒软件误报

大概是因为有 os 操作,想想怎么优化代码吧!~

7、兼容性

64 位 Python 写的程序打包后只能在 64 位的其他电脑运行,32 位的都可以运行,但 XP/7/10 之类的不同系统也可能存在问题(底层的东西笔者不懂啦);

三、关于Pycharm项目的迁移

除了打包发布以外,还经常需要转移整个项目,在本机更改目录或拷贝到其他电脑,如果是使用 Pycharm(或其他IDE)进行开发,最常见的问题就是:import失效;

针对 Pycharm 的情况,首先是将项目拷贝到其他电脑或要在本机导入其他人的项目,通过 open 导入 project 后,在左上角菜单中打开 Settings:

方法一: 重新安装相关库(若依赖较多则十分耗时);

方法二: 若拷贝的 project中 附带了 venv 目录,其中 Lib\site-packages 的包含了依赖的库,那么将当前的 python 解释器设为该 venv 目录下的 Scripts\python.exe。图中为 NewSysCrawler 和 PyProjects 两个不同项目的解释器,在不同项目中它们会自行搜索对应 site-packages 里的包。
PyQt5初学试验记录(三):Pyinstaller打包小结_第3张图片

在本机迁移项目同理,只要更改工作环境即可自动更新相关库的导入路径。若是 import 自己编写的 .py,则在左侧项目文件夹处右键,点击 Mark Directory as – Source root即可。

四、小结

1、cmd命令:
cd /d X:\filedir 进入目录,
cd ..\ 返回上级目录;

2、pyinstaller参数:
-D 打包成目录结构(-F 打包单文件),
-i 设置.exe图标 ,
-w 无窗口运行;

3、注意点: 路径指定,依赖的文件(夹);

4、参考来源:
Pyinstaller打包发布经验总结
python项目打包(自定义dll) anaconda3+pyinstaller
Python图片中的缩放实现,以及多种尺寸icon的生成
用PyQt5开发可视化爬虫软件
PyInstaller打包实战指南

5、后记:
在开发界面工具到打包的整个过程中,真是受益良多,作为小白学习到了很多东西。但是写文回顾中发现还是有许多的不足,一些不规范的操作可能不利于新手读者“走上正道”,只能说是勉强满足了个人的功能需求哈哈,今后的分享还需加强专业性和严谨性,给自己加个油!后来笔者又发现了还可以利用 qrc 文件进行资源整合,感兴趣的同学自己探索一下吧。这里是Seon塞翁,下篇再见!~

你可能感兴趣的:(PyQt5记录,python,pyqt)