PyQt5:PyQt5程序打包1

PyQt5

74篇

PyQt5:PyQt5程序打包1

导读:第一部分

LEARN MORE

正文

今天我们一起学习下PyQt5的程序打包,这里我们使用的打包工具是PyInstaller。

1

总体介绍

PyInstaller在Windows(XP或更高版本)、Mac OS X、Linux中运行。它可以创建图形窗口应用程序(不需要命令窗口的应用程序)。

原理介绍

PyInstaller读取您编写的Python脚本。它会分析您的代码,以发现您的脚本执行所需的每个其他模块和库。然后它收集所有这些文件的副本( 包括活动的Python解释器)并将它们与您的脚本放在一个文件夹中,或者可选地放在一个可执行文件中。

对于绝大多数程序,这可以通过一个简短的命令来完成:

或者添加一些选项,例如窗口化应用程序作为单文件可执行文件:

您将捆绑包作为文件夹或文件分发给其他人,他们可以执行您的程序。对于您的用户,该应用是自包含的。他们不需要安装任何特定版本的Python或任何模块。

需要注意的是PyInstaller的输出特定于活动操作系统和Python的活动版本,如:

不同的操作系统

不同版本的Python

32位或64位操作系统

你在哪个操作系统上,在哪个版本的Python下运行PyInstaller。执行PyInstaller的Python解释器是bundle的一部分,它特定于OS和字大小。

换句话说,不同的操作系统生成的应用程序可能无法兼容

文件分析

PyInstaller会查找您的程序需要的文件,您的脚本需要什么其他模块和库才能运行。

为了找到答案,PyInstaller会在您的脚本中找到所有import语句。它找到导入的模块并在其中查找import语句,依此类推,直到它具有脚本可能使用的完整模块列表。

如果您的脚本需要PyInstaller不知道的文件,您必须帮助它:

您可以在pyinstaller命令行上提供其他文件。

您可以在命令行上提供其他导入路径。

您可以编辑PyInstaller在您第一次为脚本运行时编写的myscript.spec文件。在spec文件中,您可以告诉PyInstaller有关脚本特有的代码模块。

您可以编写“钩子”文件,通知PyInstaller隐藏的导入。如果为其他用户也可能使用的包创建“挂钩”,则可以将挂钩文件提供给PyInstaller。

如果您的程序依赖于对某些数据文件的访问,您也可以告诉PyInstaller将它们包含在捆绑包中。您可以通过修改spec文件来执行此操作。

捆绑到一个文件夹

将PyInstaller应用于myscript.py时,默认结果是名为myscript的单个文件夹。此文件夹包含所有脚本的依赖项,以及一个名为myscript的可执行文件(Windows中的myscript.exe)。

您将该文件夹压缩为myscript.zip并将其传输给您的用户。他们只需解压缩即可安装程序。用户通过打开文件夹并在其中启动myscript可执行文件来运行您的应用程序。

在使用单文件夹模式时,可以轻松调试在构建应用程序时出现的问题。您可以准确地看到PyInstaller收集到文件夹中的文件。

单文件夹包的另一个优点是,当您更改代码时,只要它导入完全相同的依赖项集,您就可以只发送更新的myscript可执行文件。这通常比整个文件夹小得多。

单文件夹格式的一个小缺点是一个文件夹包含大量文件。您的用户必须在一长串名称或大量图标中找到myscript可执行文件。此外,您的用户可能会意外地将文件拖出文件夹,从而产生问题。

捆绑到一个文件

PyInstaller可以将您的脚本及其所有依赖项捆绑到一个名为myscript的可执行文件(Windows中的myscript.exe)中。

优点是您的用户可以获得他们理解的内容,即可以启动的单个可执行文件。缺点是任何相关文件(如README)必须单独分发。此外,单个可执行文件的启动速度比单文件夹捆绑包慢一点。

在尝试捆绑到一个文件之前,请确保捆绑到一个文件夹时应用程序正常工作。在单文件夹模式下诊断问题要容易得多。

特别提醒

不要将管理员权限授予单文件可执行文件(Unix / Linux中的setuid root,或Windows 7中的“以管理员身份运行此程序”属性)。在引导加载程序准备它时,恶意攻击者可能会破坏临时文件夹中的一个共享库,这是一种不太可能但并非不可能的方式。改为以单文件夹模式分发特权程序。

使用os.setuid()的应用程序可能会遇到权限错误。调用setuid后,捆绑的应用程序运行的临时文件夹可能无法读取。如果您的脚本需要调用setuid,最好使用单文件夹模式,以便更好地控制其文件的权限。

使用控制台窗口

默认情况下,引导加载程序会创建一个命令行控制台(Linux和Mac OS中的终端窗口,Windows中的命令窗口)。它为Python解释器提供了标准输入和输出的窗口。您的脚本使用print和input()是针对此处的。来自Python的错误消息和默认日志记录输出也出现在控制台窗口中。

Windows和Mac OS的一个选项是告诉PyInstaller不提供控制台窗口。引导加载程序启动Python,没有标准输出或输入的目标。当脚本具有用于用户输入的图形界面并且可以正确报告其自己的诊断时,请执行此操作。

隐藏源代码

捆绑的应用程序不包含任何源代码。但是,PyInstaller捆绑了编译的Python脚本(.pyc文件)。这些原则上可以被反编译以揭示代码的逻辑。

如果您想更彻底地隐藏源代码,可以选择使用Cython编译一些模块。使用Cython,您可以将Python模块转换为C并将C编译为机器语言。

PyInstaller可以遵循引用Cython C对象模块的import语句并将它们捆绑在一起。

此外,通过在PyInstaller的命令行上指定加密密钥,可以使用AES256对Python字节码进行模糊处理。请注意,提取密钥并获取原始字节码仍然非常容易,但它应该可以防止大多数形式的“随意”篡改。

2

PyInstaller安装

在Windows下一行命令搞定(没钱买Mac,没法演示了)

3

使用PyInstaller

pyinstaller命令的语法是:

在最简单的情况下,将当前目录设置为程序myscript.py的位置并执行:

PyInstaller分析myscript.py并执行以下操作:

将myscript.spec写入与脚本相同的文件夹中。

如果文件夹不存在,则在与脚本相同的文件夹中创建文件夹。

在build文件夹中写入一些日志文件和工作文件。

如果文件夹不存在,则在与脚本相同的文件夹中创建文件夹dist。

在dist文件夹中写入myscript可执行文件夹。

在dist文件夹中,您可以找到分发给用户的捆绑应用程序。

一些命令选项请参考帮助文档:https://pyinstaller.readthedocs.io/en/latest/usage.html

针对不同Python版本

当您需要在一个操作系统中捆绑您的应用程序但是需要不同版本的Python和支持库时,例如,Python 3版本和Python 2.7版本;或者使用Qt4的受支持版本和使用Qt5的开发版本,推荐使用virtualenv

以下是使用onefile构建的Windows应用程序的一些示例:

Python 2.7,“hello world”应用程序:3.3MB

Python 3.4,“hello world”应用程序:4.9MB

Python 2.7,使用PySide,numpy,PyOpenGL等的中型应用程序:27.4MB

onefile应用程序相当纤薄,因为它们可以压缩python库。 onedir应用程序可以大50-100%。 许多Python包有条件地导入其他一些包。

因此,为了实现超薄应用程序,建议创建一个仅包含应用程序所需依赖项的virtualenv

针对不同操作系统

如果您需要为多个操作系统分发应用程序,例如Windows和Mac OS X,则必须在每个平台上安装PyInstaller,并在每个平台上单独捆绑您的应用程序。否则可能存在不兼容情况。

4

常见问题解决方式构建时消息

分析步骤运行时,会生成错误和警告消息。如果—log-level选项允许,它们将在命令行后显示。 Analysis还将消息放在work-path =目录中名为build / name / warn-name.txt的警告文件中。

Analysis在检测到导入时会创建一条消息,并且无法找到其命名的模块。当在包(init.py模块)中声明类或函数时,也可能生成消息,并且import指定package.name。在这种情况下,分析无法判断name是否应该引用子模块或包。

“未找到模块”消息不被归类为错误,因为通常存在许多错误。例如,许多标准模块有条件地导入可能存在或不存在的不同平台的模块。

所有“找不到模块”消息都写入build / name / warn-name.txt文件。它们不会显示为标准输出,因为它们有很多。检查警告文件;通常会有几十个未找到的模块,但它们的缺失没有关系。

当您运行捆绑的应用程序并且它以ImportError终止时,就是检查警告文件的时间。然后,请参阅下面的帮助PyInstaller查找模块以了解如何继续。

构建时Python错误

PyInstaller有时会通过引发Python异常来终止。在大多数情况下,原因从异常消息中可以清楚地看出,例如“您的系统不受支持”或“Pyinstaller至少需要Python 2.7”。其他人明确指出应该报告的错误。

然而,其中一个错误可能令人费解:IOError(“Python library not found!”)。PyInstaller需要捆绑Python库,它是Python解释器的主要部分,链接为动态加载库。此文件的名称和位置因使用的平台而异。默认情况下,某些Python安装不包含动态Python库(可能存在静态链接但不能使用)。您可能需要安装某种开发包。或者,库可能存在但不在PyInstaller正在搜索的文件夹中。

PyInstaller查找python库的地方在不同的操作系统中是不同的,但在大多数系统中都检查/ lib和/ usr / lib。如果您不能将python库放在那里,请尝试在Linux中的环境变量LD_LIBRARY_PATH或OS X中的DYLD_LIBRARY_PATH中设置正确的路径(Windows系统也建议这样做)。

扩展路径

如果Analysis认识到需要一个模块,但找不到该模块,那通常是因为脚本正在操作sys.path。 在这种情况下最简单的方法是使用—paths =选项列出脚本可能搜索导入的所有其他位置:

这些路径将在spec文件中注明。 它们将在分析期间添加到当前的sys.path中。

以上内容大部分来自PyInstaller帮助手册,擅用帮助手册能够给我们解决相当多的问题,提高自己的技能。

5

最后

好的,本期就更完了!下面我们通过对一个简单的计算器进行打包操作,这个计算器如下图,我们在PyQt4的视频课程中打包的也是这个计算器(已经修改代码便于在PyQt5中运行)。

https://ke.qq.com/course/180996

如果你喜欢本篇文章,请给我点赞

赞赏(推荐)

分享给你的好友们吧!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181010G0OBBX00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券