pyside6-deploy: Qt for Python 的部署工具

pyside6-deploy 是一个易于使用的工具,用于将 PySide6 应用程序部署到不同的平台。它是 Nuitka 的封装,Nuitka 是一个 Python 编译器,将你的 Python 代码编译为 C 代码,并与 libpython 链接以生成最终的可执行文件。

最终生成的可执行文件在Windows上带有.exe后缀,在Linux上带有.bin后缀,在macOS上带有.app后缀。

注意

该工具使用的Nuitka默认版本是2.5.1。可以通过更新您的pysidedeploy.spec文件来升级到新版本。

如何使用它?

有两种不同的方式可以使用pyside6-deploy来部署你的PySide6应用程序:

方法1:使用主要的Python入口点文件

在这种方法中,您将pyside6-deploy指向包含项目主要Python入口点的文件,即包含if __name__ == "__main__":的文件。命令如下所示:

pyside6-deploy /path/to/main_file.py

运行命令时,pyside6-deploy 会将部署所需的所有依赖项安装到 Python 环境中。

如果你的主要Python入口文件名为main.py,那么你不需要指定文件名。你可以直接运行pyside6-deploy而不带任何选项,它将会正常工作。

注意

如果你的项目包含一个pysidedeploy.spec文件,该文件在第一次运行pyside6-deploy时在项目目录中生成,那么对于后续的任何pyside6-deploy运行,你可以在不指定主Python入口点文件的情况下运行pyside6-deploy。它将从pysidedeploy.spec文件中获取主文件的路径。要了解更多关于pysidedeploy.spec文件控制的部署参数,请阅读pysidedeploy

方法2:使用pysidedeploy.spec配置文件

当你第一次运行pyside6-deploy时,它会在项目目录中创建一个名为pysidedeploy.spec的文件。这个文件控制着影响部署过程的各种参数。在项目目录上后续运行pyside6-deploy时,将不需要像主Python入口点文件这样的额外参数。你也可以将pyside6-deploy指向pysidedeploy.spec文件的路径(如果它不在同一目录中),以从该文件中获取参数。这可以通过以下命令完成:

pyside6-deploy -c /path/to/pysidedeploy.spec

pysidedeploy.spec

如上文方法2所述,您可以使用此文件来控制部署过程的各种参数。该文件包含多个部分,每个部分包含多个键(被控制的参数)分配给一个值。这种文件的优点有两个方面:

  1. 使用命令行,您可以控制部署参数,而无需每次都指定它们。这些参数会永久保存在一个文件中,任何后续的运行都会让用户知道他们上次的部署参数。

  2. 由于这些参数被保存到一个文件中,它们可以被检入版本控制。这使用户对部署过程有更多的控制。例如,当你决定排除更多的QML插件,或者想要在你的可执行文件中包含更多的Nuitka选项时。

此文件也被pyside6-android-deploy工具用作配置文件。这里的优势在于,你可以有一个单一的文件来控制所有平台的部署。

pyside6-deploy 的相关参数是:

app
  • title: 应用程序的名称

  • project_dir: 项目目录。通常假设项目目录是主Python入口点文件的父目录。

  • input_file: 主Python入口文件的路径

  • project_file: 如果存在,这指向Qt Creator Python 项目文件 .pyproject 文件的路径。这样的文件确保在打包可执行文件时,部署过程永远不会考虑不必要的文件。

  • exec_directory: 生成最终可执行文件的目录。

  • icon: 用于应用程序的图标。对于Windows,图标图像应为.ico格式,对于macOS应为.icns格式,而对于Linux,所有标准图像格式都被接受。

python
  • python_path: Python可执行文件的路径。建议在虚拟环境中运行部署过程,因为某些Python包将被安装到Python环境中。

  • packages: 安装到Python环境中的Python包,用于部署工作。默认情况下,安装了Python包nuitkaordered_setzstandard。如果部署平台是基于Linux的,则还会安装patchelf

qt
  • qml_files: 逗号分隔的路径,指向与可执行文件捆绑的所有QML文件

  • excluded_qml_plugins: 使用Nuitka进行QML部署时的问题是,所有的QML插件也会与可执行文件一起打包。当插件被打包时,插件的Qt模块的二进制文件也会被打包。例如,像QtWebEngine这样体积较大的模块也会被添加到你的可执行文件中,即使你在代码中没有使用它。excluded_qml_plugins参数可以帮助你明确指定哪些QML插件被排除。pyside6-deploy会自动检查QML文件与各种QML插件的兼容性,并排除以下不存在的Qt模块:

    QtQuick, QtQuick3D, QtCharts, QtWebEngine, QtTest, QtSensors
    

    之所以只搜索上述6个Qt模块的存在,是因为它们在所有Qt模块中拥有体积最大的二进制文件。通过这种方式,你可以大幅减少可执行文件的大小。

  • modules: 应用程序使用的所有Qt模块的逗号分隔列表。就像pysidedeploy.spec中的其他配置选项一样,这个选项也是由pyside6-deploy自动计算的。然而,如果用户想要显式地包含某些Qt模块,可以将模块名称附加到此列表中,而不需要Qt前缀。例如,使用Network而不是QtNetwork。

  • plugins: 应用程序使用的所有Qt插件的逗号分隔列表。就像pysidedeploy.spec中的其他配置选项一样,这个选项也是由pyside6-deploy自动计算的。然而,如果用户想要显式地包含某些Qt插件,可以将插件名称附加到此列表中。要查看与PySide6捆绑的所有插件,请查看安装PySide6的Python的site-packages中的plugins文件夹。插件名称对应于它们的文件夹名称。

nuitka
  • macos.permissions: 仅适用于macOS。此选项列出了macOS应用程序使用的权限,这些权限可以在macOS应用程序包的Info.plist文件中找到,使用的是所谓的UsageDescription字符串。权限通常由pyside6-deploy自动找到。然而,用户也可以使用:<简短描述>的格式显式指定它们。例如,相机权限被指定为:

    NSCameraUsageDescription:CameraAccess
    
  • mode: 接受以下选项之一:onefilestandalone。默认值为 onefile。 此选项对应于运行 Nuitka 的模式。onefile 模式会创建一个单独的可执行文件,而 standalone 模式会创建一个包含可执行文件和所有必要文件的目录。standalone 模式在您希望将应用程序作为包含依赖项和应用程序所需的其他文件的目录分发时非常有用。

  • extra_args: 指定的任何额外Nuitka参数。它以空格分隔的命令行参数形式指定,就像你通过命令行使用Nuitka时一样。默认情况下,它包含以下参数:

    --quiet --noinclude-qt-translations=True
    

命令行选项

最重要的命令行选项是主Python入口点文件的路径和pysidedeploy.spec文件。如果这些文件不存在或未提供它们的命令行选项,则pyside6-deploy假定您当前的工作目录不包含PySide6项目。

以下是pyside6-deploy的所有命令行选项:

  • 主入口点文件: 此选项没有名称或标志,也不受其限制。 这使得 pyside6-deploy 可以像这样使用:

    pyside6-deploy /path/to/main_file.py
    
  • -c/–config-file: 此选项用于显式指定pysidedeploy.spec的路径

  • –init: 用于仅创建 pysidedeploy.spec 文件 用法:

    pyside6-deploy /path/to/main --init
    
  • -v/–verbose: 以详细模式运行 pyside6-deploy

  • –dry-run: 显示最终运行的Nuitka命令。

  • –keep-deployment-files: 当添加此选项时,它会保留由

    Nuitka在部署过程中创建的构建文件夹。

  • -f/–force: 当使用此选项时,它会强制通过所有输入提示。 pyside6-deploy 提示用户创建一个 Python 虚拟环境,如果尚未处于虚拟环境中。 使用此选项时,无论当前 Python 环境是否为虚拟环境,都将使用当前的 Python 环境。

  • –name: 应用程序名称。

  • –extra-ignore-dirs: 项目目录中以逗号分隔的目录名称。在搜索与项目相关的Python文件时,这些目录将被跳过。

  • –extra-modules: 以逗号分隔的Qt模块列表,这些模块将被添加到应用程序中,以防它们未被自动找到。模块名称可以通过省略Qt的前缀或包含它来指定,例如:Network和QtNetwork都可以使用。

注意事项

为了通过仅捆绑必要的插件来实现高效部署,系统上需要安装以下实用程序:

操作系统

依赖项

安装

Windows

dumpbin

随MSVC一起提供。运行vcvarsall.bat将其添加到PATH

Linux

readelf

默认可用

macOS

dyld_info

默认从macOS 12及以上版本可用

创建错误报告

如果您不确定错误是来自 pyside6-deploy 还是 Nuitka

  1. 在 Qt for Python 中创建一个错误报告。查看说明 这里

  2. 使用 --verbose 选项运行 pyside6-deploy 命令,并在 pysidedeploy.spec 文件中的 extra_args 参数中将 --quiet 替换为 --verbose。将标准输出的内容附加到错误报告中。

  3. 在错误报告中附上一个能够重现该错误的最小示例。

如果您认为这个bug源自Nuitka

  1. 尝试使用更新版本的Nuitka。你可以从生成的pysidedeploy.spec文件中的packages参数更改此设置。

  2. 如果问题仍然存在,请在Nuitka GitHub页面上创建一个错误报告。

    • 使用--dry-run选项运行pyside6-deploy以查看生成的Nuitka命令。将运行的Nuitka命令附加到错误报告中。

    • 按照Nuitka错误报告模板创建错误报告。