Qt for Python & PyInstaller#

PyInstaller 允许您将Python应用程序冻结为独立可执行文件。此安装程序支持Linux,macOS,Windows等多种系统;同时兼容第三方Python模块,如PySide6。

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

Qt 6支持状态#

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

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

在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)打开一个控制台。

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

创建一个示例

现在,考虑以下名为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())

由于它有一个UI,您需要使用--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版本:最好使用

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