Python中使用pyinstaller将pyqt所写的程序打包为exe文件 Python中使用pyinstaller将pyqt所写的程序打包为exe文件

前言

最近需要写一些小工具来辅助工作,其中一些想了想如果有一个简单的界面的话应该使用起来更方便一些,由于python的方便性,大概试了一下python中的几个常用的图形库,如wxPythonTkinter等,通过比较,感觉还是pyqt做出来的界面美观性要强一些,而且可移植性较好。

在写完程序的大概之后,即在IDE里运行程序可以出现想要的界面了,现在的一个问题是,以后打开这些程序的时候,若要每次都要先打开IDE然后运行程序,这个过程未免太过繁琐,所以想要将所写的程序打包为exe文件,这样今后打开的时候会方便许多,在其它机器上工作的时候移植也要方便。

本文就主要介绍如何将用pyqt所写的程序打包为exe程序。

环境准备

1、 anaconda下2与3共存的方式与在3的环境中安装包的方法

在本次尝试中遇到了许多问题,其中绝大部分问题最后归论起来还是pyqt环境安装的有问题,所以在安装pyqt的过程中一定要注意。

我的python的版本为2.7,是用anaconda2安装的环境。但是pyqt5对于python2的支持并不好,我在多次尝试后,始终没有找到合适的安装方法,因此最后还是在python3的环境中进行的操作。但是,如果只是想要在程序中实现界面的话,2.7是没有任何问题的,这里只是在打包exe过程中遇到了问题。

简单说一下anaconda,anaconda是一种集成了大多数常用的库的python环境,对于python的安装来说是一种非常方便的方式,anaconda的2与3两个版本便对应着python的2与3。在anaconda中2是可以与3共存的,安装的方法也比较简单,我是先安装的2,在安装3的时候需要主要要装到2的envs这个文件夹中新建的文件夹,如C:UsersxxxAnaconda2envspython3,再有就是安装的时候在这个界面最好两个选项都不要打勾:
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
其余的基本一路默认就可以,安装完成之后,python3便可以作为一个独立的环境来进行使用了,在IDE中可以选择…/envs/python3这个文件夹下的python3的解释器,即调用了python3的环境。而在控制台中,默认的初始情况下,直接输入python,进入的是默认的python2.7的环境(因为之前的系统变量中为2.7的环境,而安装anaconda3的时候并没有修改系统变量),使用python3 的方法为输入语句activate python3(这里的python3即为上面envs里面新建的文件夹的名称),此时系统默认的python的环境即更改为了python3,此时的pip也会将包装到3的环境中。此时,若输入python则会进入python环境并显示目前的python版本为python3.6:
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
而这里的第二行的开头可以看到括号里的python3,这里说明默认环境已经更改到了python3。而之后的说明若无特殊说明均默认为在已经进入了默认python3的环境。

2、 配置SIP

我们要利用PyQt5来写界面,所需的一个依赖库便是sip,sip是RiverBank(也就是PyQt的开发商)开发的用于PyQt的Python/C++混合编程解决方案。SIP是一种工具,可以将Python与C和C++的库进行绑定,它包括代码生成器和python等模块,这使得Python等解释性编程环境可以开发现有的C或者C++的库。
在这里,sip属于python的一个依赖库,可以直接使用命令进行安装

pip install sip

###3、 配置PyQt5
接下来便就是主角PyQt5了,在python3中可以直接使用pip进行安装:

pip install PyQt5

当然这里第二步和第三步会出现许多错误,我在后面会提到。
###4、 配置pyinstaller
这里网上许多资料里都使用下载包然后安装的方式,但是我也是简单地采用了pip的方式进行的安装,并没有出现问题。

pip install pyinstaller

测试

这里是测试的时候用的代码,可以显示出一个简单的界面:

import sys
from PyQt5 import QtCore, QtWidgets

app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
widget.resize(320, 240)
widget.setWindowTitle("Hello, PyQT!")
widget.show()
sys.exit(app.exec())

将代码写完后将其保存为hello_PyQt.py文件。

之后打开控制台,输入activate python3将默认的python环境设置为python3,然后输入cd 路径进入刚刚的.py文件所在的路径:

Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件

然后输入pyinstaller -F -w hello_PyQt.py将代码打包为exe文件(可以在网上查询各种不同参数含义,这里的-F与-w分别为保存为一个文件与运行exe文件时不显示控制台):
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
最后可以看见此时便保存成功了,在刚刚的路径中的多出来几个文件夹与文件,在build文件夹中可以查看pyinstaller运行时的一些信息,而在另一个dist文件夹中便有着hello_PyQt.exe文件了,即为我们需要的exe文件。此时运行该文件:
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
可以看到出现了我们代码中所实现的窗口,此时便运行成功。

过程中遇到的问题

1、 在配置sip时报错

在配置sip时报错:
···
Could not find a version that satisfies the requirement sip (from versions: )
No matching distribution found for sip
···
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
报错原因为:此时并没有输入activate python3命令进入默认python3环境,而sip对于python2.7支持并不好,因此无法直接pip进行安装。

2、 在打包过程中报错

在使用Pyinstaller进行打包的过程中,报错:
···
Exception: Cannot find PyQt5 plugin directories
···
原因与上一条相同,没有将默认Python环境更改为python3。

3、 在运行exe时报错

这里是整个环节中比较棘手的一环了,我遇到的主要问题是有两点:
第一次是使用python2.7到了这一步,运行exe一直不成功,尝试了很多种方法,但是都没有完美解决的,之后用3.6来重新测试。
第二点是在用python3.6的时候遇到的,当时为了测试并没有加-w参数,在运行exe文件时会一闪而过一个控制台信息,内容为

ModuleNotFoundError: no modules named 'PyQt5.sip'

这里的原因是,上面所配置的QtPy5SIP的版本是需要对应的,如果没有对应的话,这一步就会出现这样的问题。

因此,我们可以根据我们已经安装的SIP的版本去确定我们所需要的PyQt5的版本。

首先,先将已有的PyQt5的包进行删除,运行命令(记得进入Python3的默认环境):

pip uninstall pyqt5

然后查看已经安装过的sip的版本,方法为进入python环境后,先import sip,然后输入sip.SIP_VERSION_STR命令,即可查看:
Python中使用pyinstaller将pyqt所写的程序打包为exe文件
Python中使用pyinstaller将pyqt所写的程序打包为exe文件

可以看到我的sip的版本为’4.19.8‘,之后需要做的便是根据已经安装的sip的版本来确定我们需要安装的PyQt5的版本,这里,要注意的是,两个版本号在字面上并不是一一对应的,我还没有找到一个明确的版本之间的对应关系。目前采用的方法为去查看两个包的历史发布日期,然后选择与目前sip包发布日期相近的PyQt5的版本,比如我现在的sip的版本为’4.19.8‘可以查到其对应的页面为:sip 发布历史,发布日期为2018年2月27日,然后再查看PyQt5 发布历史,可以看到有同一天发布的PyQt5,其版本为‘5.10.1’,因此,我们此时需要安装的便就是这个版本,此时,运行命令:

pip install PyQt5==5.10.1

成功之后便安装好了该版本的包,此时运行就不会出现问题了。

4、在运行exe文件时弹窗报错FATAL ERROR

在运行exe文件的时候,弹出一个FATAL ERROR窗口,错误信息为:

fail to execute script hello_PyQ

首先确定是否是在python2的环境中打包的(运行pyinstaller时),若是的话,应重新在python3 的环境打包。若已经为在python3的环境中打包的,则按照第三个错误中的方法来检查一下,查看包之间的对应关系,我这里最后就是这么解决的。