Qt for Python & PyInstaller

PyInstaller 允许你将你的Python应用程序冻结成一个独立的可执行文件。这个安装程序支持Linux、macOS、Windows等操作系统;并且也兼容第三方Python模块,例如PySide6。

更多详情,请参阅官方文档

Qt 6 支持状态

截至2021年3月,Qt 6尚未得到支持。PyInstaller无法正确部署Qt;Qt插件未被复制。因此,使用--onefile是不可能的。

可以在非--onefile的情况下使用PyInstaller,通过在运行PyInstaller后手动将Qt插件、QML导入和翻译复制到dist目录中。

在Windows上,可以通过从Qt SDK运行windeployqt工具来实现,该工具作用于dist目录中的Qt库,例如:

windeployqt dist\app\Qt6Widgets.dll

准备

通过以下命令使用pip安装PyInstaller

pip install pyinstaller

如果您使用的是虚拟环境,请记得在安装PyInstaller之前激活它。

安装后,pyinstaller 二进制文件位于您的虚拟环境的 bin/ 目录中,或者您的 Python 可执行文件所在的位置。如果该目录不在您的 PATH 中,请在运行 pyinstaller 时包含完整路径。

警告

如果您的系统路径中已经安装了PySide6或Shiboken6版本,PyInstaller将使用它们而不是虚拟环境中的版本。

冻结应用程序

PyInstaller 有许多选项可供使用。要列出所有选项,请运行 pyinstaller -h

有两个主要特点:

  • 将整个项目(包括共享库)打包成一个可执行文件的选项 (--onefile)

  • 将其放置在包含库的目录中的选项

此外,在Windows上,当命令正在运行时,您可以使用-c选项 (或等效的--console--nowindowed)打开一个控制台。

否则,您可以在macOS和Windows上指定不打开这样的控制台窗口,使用-w选项(或等效的--windowed--noconsole)。

创建一个示例

现在,考虑以下脚本,名为 hello.py:

import sys
import random
from PySide6.QtWidgets import (QApplication, QLabel, QPushButton,
                               QVBoxLayout, QWidget)
from PySide6.QtCore import Slot, Qt

class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",
            "Hola Mundo", "Привет мир"]

        self.button = QPushButton("Click me!")
        self.text = QLabel("Hello World")
        self.text.setAlignment(Qt.AlignCenter)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        # Connecting the signal
        self.button.clicked.connect(self.magic)

    @Slot()
    def magic(self):
        self.text.setText(random.choice(self.hello))

if __name__ == "__main__":
    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.resize(800, 600)
    widget.show()

    sys.exit(app.exec())

由于它具有用户界面,您可以使用--windowed选项。

继续的命令行如下所示:

pyinstaller --name="MyApplication" --windowed hello.py

此过程创建两个目录:dist/build/。应用程序可执行文件和所需的共享库被放置在 dist/MyApplication 中。

要运行应用程序,请转到 dist/MyApplication 并运行程序:

cd dist/MyApplication/
./MyApplication

注意

目录内的 dist/ 和可执行文件具有相同的名称。

如果您希望将所有内容打包成一个可执行文件,而不需要旁边的共享库,请使用--onefile选项:

pyinstaller --name="MyApplication" --windowed --onefile hello.py

这个过程需要更长一点时间,但最终你会在dist/目录中有一个可执行文件:

cd dist/
./MyApplication

一些注意事项

PyInstaller 问题

如前所述,如果可用,PyInstaller 会悄无声息地选择系统安装的 PySide6 或 Shiboken6,而不是你的 virtualenv 版本。如果这两个版本相同,这一点可以忽略不计。

如果您正在使用不同的版本,这可能会导致令人沮丧的调试会话,当您认为正在测试最新版本时,但PyInstaller正在使用较旧的版本。

安全说明

  • 当使用 PyInstallervirtualenv 时,请确保系统中没有安装 PySide6 或 shiboken6。

  • 在编译之前,多次使用pip -uninstall pyside6 pyside6_essentials pyside6_addons shiboken6 -y,直到找不到任何程序为止。

  • Pip 通常是一个好工具。但为了确保 100% 的准确性,你应该直接从 site-packages 中删除 PySide6 和 shiboken6 文件夹。

  • 确保使用正确版本的pip。最安全的方法确实是运行正确的pip,是使用你想要的Python:而不是使用pip命令,最好使用:

    <path/to/your/>python -m pip