使用pyinstaller打包python PyQt5程序
当你有打包你的python应用的需求以后,你可能会像搜索引擎寻求帮助,你或许曾经搜索过“python 转 exe”,“python打包”等等这样的字眼,你或许曾看到过各种各样的相关解决方案,本文介绍的是其中的一种,但是可以负责任的说,这是目前最好的方案,并且是跨平台最好的方案,也就是说使用这个叫pyinstaller的工具,你可以把同样的代码打包在windows,linux以及macos上运行。
这个工具的名称就是pyinstaller,官方主页:
这个工具将打包工作封装成一条简单的指令就能完成的动作。
准备
工具准备
第一件事情当然是安装这个库了,和往常一样,使用pip
pip install pyinstaller
源代码准备
因为我们是针对一个gui应用来打包,那么我们需要简单的改造一下源代码,如果你是在打包命令行,则不需要进行这个操作。
首先,我们要创建一个入口文件,名称为 wifidrop.pyw,名字无所谓,它将成为你最终的软件名称,这里需要注意的是,我们的文件后缀为pyw,比py文件后缀多了一个w,而w的意思是window,也就是说告诉python环境,我们这个软件是一个窗口应用,如果不这么做,在运行软件的时候,除了有我们的gui界面以外,python还会留 一个命令行窗口在后边,这显然不是我们想要的,而使用了pyw后缀以后,python则不会显示命令行窗口。
在 wifidrop.pyw 不需要做什么太多东西,仅仅是简单的调用main.py中的main函数就可以了。
import sys from main import main if __name__ == '__main__': excode = main() sys.exit(excode)
打包
做好代码相关的准备以后,就可以使用pyinstaller来打包软件了,过程也非常简单,一行命令就能解决,在命令行中运行
pyinstaller --clean -f -w wifidrop.pyw -i treetog-i-documents.ico
参数说明
–clean :告诉pyinstaller删除缓存和临时文件
-f :告诉pyinstaller将打包的结果放在一个exe文件中,也就是说最终结果将只有一个exe文件,如果不使用这个参数,那么结果会是一个exe加很多依赖文件,不利于我们分发软件。
-w :告诉pyinstaller我们要生成的是一个窗口应用
-i :为我们的应用指定一个图标,否则默认的话会使用python图标
一般来说,这些参数就足够日常使用了,如果需要更深入的功能,比如加密等等,就需要阅读手册了。
这条命令成功运行完以后,你将会在项目目录中看到build和dist两个文件夹,最终的可执行文件就放置在dist文件家中。
针对pyqt应用的改进
目前的小问题
当我们尝试运行在dist中生成的wifidrop.exe文件的时候,你将发现,程序无法运行,不知道你还有没有印象,至今为止,我们都一直在main.py中使用loadui函数加载qt creator创建的ui的方式来创建gui界面,那么仔细观察一下dist文件夹中,里边并没有ui文件,对吧?
因为pyinstaller仅仅是一个py应用的打包工具,它并不知道其他的文件的存在,所以,你可以尝试把我们的两个ui文件拷贝到dist文件夹中之后再运行这个exe。
你会发现现在应用可以正常使用了。但是这样会不会有什么风险?
对了,ui文件说白了是一个xml格式的文本文件,如果使用我们软件的人有意或者无意的修改了这两个文件中的内容,我们的软件极有可能就没办法运行了,因此,在分发我们的软件的时候,要避免使用ui文件。
ui文件的好处是在开发的时候,可以迅速的通过qt creator修改ui。
解决办法
当然pyqt也提供了很好的解决办法,它提供了一个小脚本,可以帮我们把ui文件转成py文件,并将ui转换成类。我们通过运行下边这两条命令,将mainwindow和dialog转成python类。
python -m pyqt5.uic.pyuic -x dialog.ui -o dialog.py python -m pyqt5.uic.pyuic -x mainwindow.ui -o mainwindow.py
每一个ui文件会对应一个py文件,而py文件中会有相应的类。
有了py模块以后,我们还需要在实例化ui的地方(也就是main.py)中将加载ui文件的方式改为实例化python类的方式来加载ui,分别要修改mainwindow和senddialog的初始化函数,选择2 option的方式来加载ui
class mainwindow(qmainwindow): """main window""" def __init__(self): super(mainwindow, self).__init__() # ui setup - 1 option # dynamic load ui for development purpose # self.ui = loadui('./mainwindow.ui', self) # use py to setup ui - 2 option self.ui = ui_mainwindow() self.ui.setupui(self) self.setstatusbar(none) # https://doc.qt.io/qt-5/qmainwindow.html#setstatusba
class senddialog(qdialog): def __init__(self, url_list, socket_server_thread, device_discover_thread, socket_broadcast): super(senddialog, self).__init__() # ui setup - 1 option # dynamic load ui for development purpose # self.ui = loadui('./dialog.ui', self) # use py to setup ui - 2 option self.ui = ui_dialog() self.ui.setupui(self)
再次打包
代码修正之后,我们来使用上边相同的pyinstaller命令打包,成功运行后,点击生成的wifidrop.exe,你会发现在无需ui文件的情况下,软件也能很好的运行了。
代码仓库说明
本文中用到的打包命令和ui转py命令,可以在github 仓库 https://github.com/pythonlibrary/wifidrop 中的 tutorial-6-direct-dist 和 tutorial-6-dist tag下找到,这两个tag的区别是:前一个使用了加载ui文件的方式显示ui,后边一个修正了这个问题,使用类实例化的方式显示ui。
上一篇: 新加坡提出智慧校园计划 教学傍上物联网
下一篇: Vuejs 基础与语法
推荐阅读
-
使用pyinstaller打包python PyQt5程序
-
Python中使用MELIAE分析程序内存占用实例
-
python程序打包问题详情
-
处理pyinstaller打包python程序时VideoCapture()不响应问题
-
Python学习之旅:使用virtualenv创建Python环境及PyQT5环境配置
-
在Python程序中操作文件之isatty()方法的使用教程
-
使用PDB简单调试Python程序简明指南
-
Windows下用py2exe将Python程序打包成exe程序的教程
-
使用Python开发windows GUI程序入门实例
-
使用Python的Tornado框架实现一个一对一聊天的程序