Pyinstaller打包用spec添加资源文件,亲测可用

技术标签: Python

最近写的翻译软件——transdocx,就是给普通用户而非Python程序员用的,所以它必须是一个开箱即用的软件,普通用户下载下来就能双击运行。

Pyinstaller打包用spec添加资源文件

而Python作为一个脚本语言,要运行是必须有解释器的,它不能像C/C++那样编译成二进制。同样,也不能要求普通用户首先安装Python解释器、再安装依赖的包、最后运行transdocx。所以,需要把Python写好的软件打包成一个exe程序,让用户双击既可以使用。打包Python程序的最好的工具可能就是pyinstaller了。

下面我就结合transdocx打包的过程来讲讲pyinstaller的使用,平台是Windows,Linux和macOS类似。

一、用pyinstaller给纯Python代码打包

如果你的软件中只有.py文件,即Python代码文件,不包括图标、图片等资源文件,那么使用pyinstaller打包是非常简单的,往往只需要下面一行命令即可:

pyinstaller -F -w -i icon.ico transdocx.py

第一版本的transdocx就是这样完成的。其中的几个选项:
-F 把整个软件(包括依赖的各种库文件)打包成单一文件;
-w 禁止Windows的命令行窗口。不然双击exe时会打开一个黑乎乎的dos窗口;
-i 生成的exe文件会带有这个图标,有识别度也更好看;
最后的transdocx.py就是翻译软件的入口程序。

运行完上面的命令,会在当前目录下生成一个transdocx.spec文件和两个文件夹build和dist,其中dist里面就是最终生成的exe文件,把这个文件发给普通用户就可以了。当然,你要先自己测试没有问题。

transdocx.spec 是于pyinstaller生成的配置文件,下次打包时,可以不运行上面带参数的命令,而直接运行:

pyinstaller transdocx.spec

二、用pyinstaller给带有资源文件的代码打包

第二版为了支持PDF,添加了目录bin/下面的相关资源文件,主要是:
pdftotext.exe : Windows下面的提取PDF文本内容的命令行工具;
pdftotext : Linux下面提取PDF文本内容的命令行工具;
default.docx : 生成docx的默认模板文件。

提取PDF内容是通过Python的subprocess模块调用命令行工具pdftotext.exe 实现的。如果按照上面比较简单的打包方式,就会报错:找不到这个命令行工具。因为这些资源文件没有被打包到最终的exe文件。

要把这些资源文件包含进去,可以给pyinstaller添加选项,也可以修改spec文件。我通过修改transdocx.spec来实现:

给spec添加资源文件路径

(关于spec的说明可以查看pyinstaller的官方文档)
添加过程还是很简单的,看图中红框部分就是。
前面pyinstaller 自动生成的spec文件中,binaries原本是空的:

binaries=[]

就是一个空的list,把要添加的资源文件以tuple的形式传入,tuple的第一个元素是资源文件的路径,第二个元素是打包后存放资源的文件夹。比如:

(‘./bin/pdftotext.exe’, ‘bin’)

就是把 ‘./bin/pdftotext.exe’ 打包后放到bin目录下面。打包后的目录跟Python代码的目录结构一直即可,pdftotext.exe原先放在bin下面可以让程序运行,那么打包后也放在bin下面即可。

在spec文件中添加好要包含的资源文件再次打包就可以把资源文件打包到最终的exe文件了。然而,这时得到的最终exe还是不能运行! 报的错误还是找不到相关文件。

三、修改资源文件路径以保证打包结果能执行

为什么还不能运行?这样从pyinstaller打包后的exe的运行机制讲起。打包得到的exe文件是一个可自解压的程序,它会把这个exe文件中包含的文件打包到一个名为 _MEIxxxxxx 的临时目录下面,这个目录在系统的临时文件夹下面(Linux下是 /tmp),当程序退出时,会自动清空删除这个临时目录 _MEIxxxxxx。

我们先来看看这个临时目录 _MEIxxxx 里面都是些什么,下面截图是Linux下面的,Windows类似,只不过路径不一样,Windows下是.dll等。

spec mei临时目录

其中的bin目录下就是我添加的资源文件。

最终的exe文件有可能放在任何目录执行,其当前目录下不会有bin目录下面的资源文件,而是被解压到了临时目录下面,所以程序报错找不到相关文件。

因此,我们要在程序中指定资源文件的路径,使得它在非打包模式和打包模式下运行时都能找到相关资源文件。这需要添加一个路径解析函数:

给spec添加一个路径解析函数

这个函数很简单,把资源的相对路径转换为绝对路径。如果找到 _MEIPASS 路径就以此为资源的基准路径,否则以当前路径为基准路径。

代码中任何使用资源文件的相对路径都用该函数转换一下即可保证资源文件可以被找到。比如代码中:

转换spec资源文件路径

可以从transdocx的源码中查找更多resource_path的示例。

至此,打包的问题完美解决了。再次使用spec打包一下,看看exe应该可以正常运行了。

双击exe运行正常,选取一个PDF文件,点击“翻译”。纳尼?!又报错!!

双击pyinstaller打包后的程序出错

一番搜索后,stackoverflow上找到了原因:
https://stackoverflow.com/questions/337870/

问题出在subprocess上面:

要使用subprocess pipe来打包

简单来说就是,打包是关闭了命令行窗口,stdin, stdout 无处安放。
所以,把它们用subprocess.PIPE 管道代替即可。
shell=True 可以防止执行subprocess.Popen()时闪现一个黑糊糊的dos窗口。

这时候,才算完美解决了pyinstaller打包的问题。总结一下pyinstaller打包的过程:
(1)pyinstaller -F -w xxx.py;
(2)修改上一把生成的xxx.spec文件,添加资源文件;
(3)pyinstaller xxx.spec 打包为exe文件。

来源:https://www.yuanrenxue.com/tricks/pyinstaller-spec.html


智能推荐

Qt中怎么添加资源文件

添加资源文件 1、将资源放入 工程中(建议) 2、添加资源文件 3、为资源文件 添加资源 案例:给菜单项添加图标 1、将资源放入 工程中(建议) 2、添加资源文件 3、为资源文件 添加资源 前缀随便写尽量简单以便后面使用 选择所需要的资源 注意:需要点击一下构建,等待右下角进度条走完 如果需要重新添加资源文件; 案例:给菜单项添加图标 查找相关函数api...

QT项目中添加资源文件

首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的。教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈~我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转到教程                   工程文...

Qt笔记-添加资源文件

Qt使用过程中需要添加资源文件,比如图片、动画等。 创建资源池文件 在工程目录上单击右键-->添加新文件,在弹窗中“文件和类”选择Qt,然后选择Qt resource file。此时需要输入资源文件的名称。其实这里可以把他理解为一个资源池的名字,在创建的这个资源文件中可以包含多个具体的文件。 点击完成后,工程里会添加一个“Resources目录&rdquo...

QT添加外部资源文件

1、可以使用多种方法对其进行编辑,在资源编辑器中编辑时,首先要设置一个前缀,即在该qrc文件下的相对路径,如果与该qrc文件在相同的文件夹中,就只需要将前缀设为/即可。然后将设置的路径下自己需要的文件添加进来,在引用的时候只需要使用:符号即可(例如newAction->setIcon(QIcon(":/filenew.png"));)。...

【23种设计模式】之 代理模式(Representative Pattern)

代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问。   使用代理模式创建代表(representative)对象,让代表对象控制某对象的访问,被代理的对象可以是远程的对象、创建开销大的对象或需要安全控制的对象。 代理控制访问:就好比客户端不知如何和远程对象沟通,通过远程代理控制访问,直接处理网络上的戏剧节。 RMI访问图...

猜你喜欢

Girls and Boys(HDU-1068)

Problem Description In the second year of the university somebody started a study on the romantic relations between the students. The relation "romantically involved" is defined between one ...

有趣的8个IT冷知识

阅读本文大概需要 2.8 分钟。 想要成为一名成功的程序员,我们除了了解不同编程语言的设计思路,也应当了解编程的发展历史,从而判断未来的编程技术将走向何方。接下就为大家普及下计算机发展历程中的8个冷门小知识!   01 第一台电脑为蒸汽驱动 作为公认的编程之父,Charles Babbage发明了世界上首批计算机之一。他将这台新设备称为分析引擎。其体积超过一栋房屋,由六台蒸汽机驱动并使用...

顶篷11秒开启 迈凯伦720S Spider正式发布

近日,我们从相关渠道获悉,迈凯伦720S Spider正式发布,这也是迈凯伦Track25商业计划下的第二款新车型。相比硬顶版本,新车拥有一套可在11秒内完成开启/闭合的硬顶敞篷结构。 迈凯伦720S Spider基于其硬顶Coupe版本打造而来,由于迈凯伦的全碳纤维座舱Monocage II集成有翻滚保护结构,所以敞篷版没有在硬顶版的基础上进行额外加强。外观设计上,新车将配备全新的前19寸后20...

SpringBoot从0到实战1:10分钟配置环境及HelloWorld项目

什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。 该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。 学 springboot 需...

2021-07-15

基于Openstack的云计算IaaS部署实战 云计算部署实战Part1 - 制作CentOS 模板镜像 【实验目的】 掌握搭建 CentOS 模板镜像 熟练掌握Linux命令的使用 掌握VMWare、XShell等客户端的使用 【实验环境】 内存:至少4G 硬盘:至少空余50G 操作系统: 64位 Windows系统。 资源百度云 链接:https://pan.baidu.com/s/1gwed...

问答精选

ArrayAdapter add method casting Illegal state exception

I have a problem adding items to my array adapter. Here is the code If the code is put in the onCreate method, it works! If i comment the line it works! I've tried almost everything but with no result...

Can I read iBeacon data using AS3/Air?

I am wanting to develop a simple micro location app using iBeacons (just arrived today...how exciting). I have zero experience coding native in iOS and Android however have developed several apps usin...

How do I know if an embedded systems project is using an embedded operating system?

I followed these instructions and was successfully transmitting IEEE 802.15.4 frames on a GINA Mote. I know it was working because I have a packet sniffer that captured transmitted packets. Here is th...

After closing the modal dialog refresh the base view

suggestion and code sample I am new to Backbone marionette, I have a view ("JoinCommunityNonmemberWidgetview.js") which opens a modal dialog ("JoinCommunityDetailWidgetview.js").On...

c++ how to read a file and split it's lines

I'm trying to read a file and split each line (so instead of the line "I walk my dog every day" I would have "I", "walk", "my", "dog", "every&quo...

相关问题

相关文章

热门文章

推荐文章

相关标签

推荐问答