前言:本记录为笔者自学过程中的简单笔记,说明了从安装库到最终打包成.exe的过程,分为三个部分,供初学者参考交流,存在表述有误的部分还请读者们多多指教,下方为第三部分目录。
笔者之前制作了一个基于 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 中,便于调试。
修改好 xxx.spec 后再次执行:
pyinstaller -w -D xxx.spec
下面来看看可能遇到的问题:
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),笔者用了其他方法做关联故未填写。如此一来,第一波问题就应该解决了。
程序执行中相关的本地文件(如笔者的爬虫工具需要的 cookie 会从本地 .txt 中载入历史记录),如果在 datas 中没有设置可能会出现该问题,笔者的解决办法是直接把需要的文件(夹)放在生成的 .exe 根目录中,在源码中要注意路径的指定,如 .\Files
为 .exe 根目录下的 Filepath 文件夹, ..\OtherFiles
为 .exe 上级目录中的另一个文件夹;
编辑至此,笔者有点忘了这个错误是在什么情况下产生的了……莫名其妙的就解决了。好像是什么权限不足,推测是笔者的爬虫工具会把爬取的数据输出一个 .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) # 写入
检查一下 pyinstaller 输入的参数格式;
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 的情况;
至此,图标问题勉强解决了(后来发现打包单文件似乎都能成功…)。
另外,推荐一个图标绘制器 Greenfish Icon Editor Pro,想要自己动手设计图案的同学可以尝试一下(笔者的爬虫工具图标一开始是用 sai 瞎画的一个爪子)。
大概是因为有 os 操作,想想怎么优化代码吧!~
64 位 Python 写的程序打包后只能在 64 位的其他电脑运行,32 位的都可以运行,但 XP/7/10 之类的不同系统也可能存在问题(底层的东西笔者不懂啦);
除了打包发布以外,还经常需要转移整个项目,在本机更改目录或拷贝到其他电脑,如果是使用 Pycharm(或其他IDE)进行开发,最常见的问题就是:import
失效;
针对 Pycharm 的情况,首先是将项目拷贝到其他电脑或要在本机导入其他人的项目,通过 open 导入 project 后,在左上角菜单中打开 Settings:
方法一: 重新安装相关库(若依赖较多则十分耗时);
方法二: 若拷贝的 project中 附带了 venv 目录,其中 Lib\site-packages 的包含了依赖的库,那么将当前的 python 解释器设为该 venv 目录下的 Scripts\python.exe。图中为 NewSysCrawler 和 PyProjects 两个不同项目的解释器,在不同项目中它们会自行搜索对应 site-packages 里的包。
在本机迁移项目同理,只要更改工作环境即可自动更新相关库的导入路径。若是 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塞翁,下篇再见!~