【教程】Nuitka | Python打包exe新工具
转载自:https://cloud.tencent.com/developer/article/2532039
https://liucjy.blog.csdn.net/article/details/146055485
打包工具对比
PyInstaller
- 特点:最常用的打包工具,支持 Windows、Linux 和 macOS。
- 优点:
- 操作简单,适合快速打包。
- 支持将应用打包为单个
.exe文件(--onefile参数)。 - 自动分析依赖项,减少手动配置。
- 缺点:
- 生成的可执行文件体积较大,尤其是在包含大型库(如 Pandas、PyTorch)时。
- 启动速度可能较慢,因为需要在运行时解压资源。
- 适用场景:快速部署、GUI 应用、命令行工具等。
Nuitka
- 特点:将 Python 代码编译为 C 语言,再生成可执行文件,提升性能并增强代码保护。
- 优点:
- 生成的可执行文件运行速度更快。
- 源代码难以反编译,增强安全性。
- 支持将所有依赖打包为独立目录或单个文件。
- 缺点:
- 需要安装 C 编译器(如 gcc、MSVC)。
- 首次编译时间较长。
- 适用场景:对性能和代码保护有较高要求的应用。
py2exe
- 特点:专为 Windows 设计的打包工具,历史悠久。
- 优点:
- 操作简单,适合小型项目。
- 缺点:
- 仅支持 Windows。
- 不支持跨平台打包。
- 适用场景:仅面向 Windows 用户的小型应用。
Nuitka安装
pyinstaller使用最方便,但exe实在太大了,一个tkinter窗口程序打包为200MB,因此转向Nuitka。
pip install nuitka

Nuitka打包
Nuitka的功能很强大,因此配置项也比较多,不过一般来说以下应该够用了。
nuitka --windows-console-mode=disable --onefile --enable-plugin=tk-inter --windows-icon-from-ico=app.ico --remove-output --follow-imports --enable-plugin=no-qt --noinclude-pytest-mode=nofollow --output-dir=build/ your.py

|
参数 |
含义与作用 |
|---|---|
|
nuitka |
调用 Nuitka 编译器 |
|
your.py |
要打包的 Python 源代码文件 |
|
--windows-console-mode=disable |
告诉 Windows 不要为程序创建控制台窗口(隐藏黑框),用于 GUI 程序 |
|
--onefile |
将所有内容打包成一个单独的 .exe 文件,便于分发,启动慢 |
|
--standalone |
会生成一个包含 .exe 和所有依赖文件的文件夹,启动快,占用空间大,适合开发调试、便于查看依赖结构。与onefile二选一。 |
|
--enable-plugin=tk-inter |
启用 Nuitka 提供的 Tkinter 插件,自动处理 Tkinter 相关依赖和数据文件(如 Tcl/Tk DLL、字体、图标等)。需要但没加时候会给warning。有:tk-inter|PySide6|PySide2|PyQt6|PyQt5 |
|
--remove-output |
删除输出文件夹中的 .build文件夹 |
|
--windows-icon-from-ico |
添加图标 |
|
--follow-imports |
自动递归跟踪并包含所有你代码中导入的模块 |
|
--jobs=4 |
限制并行编译线程数,不然跑满CPU卡死电脑 |
|
--enable-plugin=no-qt |
避免误加载 Qt 插件,减少打包复杂度和体积。确实用了Qt就不要加 |
|
--include-data-files=src/*.txt=. |
手动包含非代码资源文件,可选 |
|
--output-dir=build/ |
指定输出目录 |
|
--noinclude-pytest-mode=nofollow |
避免自动包含测试依赖,从而精简依赖体积 |
|
--show-progress |
显示构建进度,用于调试或观察编译流程 |


对于简单的代码,实测效果没啥差别。对于复杂代码打包,可能会遇到问题,需要慢慢调。
第一章: Python 绑定的 Qt 库——PySide6 与 PyQt6 的比较
在开发跨平台桌面应用程序时,Qt 是一个不可忽视的强大工具。而对于 Python 开发者来说,PySide6 和 PyQt6 提供了与 Qt 框架进行交互的两种主要途径。它们在外观和功能上相似,但它们的使用背景和许可证策略却存在一些重要差异。在我们深入探索它们的区别之前,先不妨思考一下哲学问题:选择的自由和责任并行而至。我们面对 PySide 和 PyQt 时,正是如此——选择了某个工具,便意味着在后续开发中需要承担由其带来的许可证和支持责任。
1.1 PySide6 与 PyQt6 的基本介绍
PySide6 和 PyQt6 都是基于 Qt 6 框架的 Python 绑定,旨在让 Python 开发者能够利用 Qt 提供的强大功能,构建漂亮且高效的桌面应用程序。无论你选择其中一个,都会使用到 Qt 提供的同一套控件、信号槽机制以及图形视图框架,因此在大多数情况下,PySide6 和 PyQt6 的使用体验是非常相似的。
1.1.1 PySide6:Qt 官方推荐的 Python 绑定
PySide6 由 Qt 官方(The Qt Company)提供支持,它是 Qt 的官方 Python 绑定。最重要的特点之一是,PySide6 使用了 LGPL(Lesser General Public License) 许可证,这使得它可以在商业项目中使用而不需要支付商业许可费用。这种许可证的宽松性使得它成为开发闭源项目时的首选工具。
1.1.2 PyQt6:成熟的第三方 Python 绑定
与此相对,PyQt6 是由 Riverbank Computing 提供支持的。它同样基于 Qt 框架,具有非常成熟的功能和稳定性。PyQt6 使用 GPL(General Public License) 许可证,这意味着,如果开发者选择将其用于闭源项目,必须购买商业许可证。对于开源项目,PyQt6 依然是免费的。
1.1.3 主要差异:许可证
| 特性 | PySide6 | PyQt6 |
|---|---|---|
| 许可证类型 | LGPL(允许商业闭源项目) | GPL(商业闭源需要购买许可证) |
| 适用场景 | 适用于商业和开源项目 | 适用于开源项目,闭源项目需付费许可证 |
这表格清晰地显示了两者在许可证方面的差异,PySide6 在自由使用和商业项目中具有明显优势,而 PyQt6 更适合开源项目。
1.2 两者的相似性与差异性
尽管 PySide6 和 PyQt6 作为 Qt 的 Python 绑定在很多方面非常相似,但它们在一些细节上存在差异。我们可以从以下几个维度来比较这两者。
1.2.1 功能和性能差异
在功能层面,PySide6 和 PyQt6 提供的 API 基本一致,且两者都能够调用 Qt 提供的强大功能。然而,PySide6 作为官方 Qt 绑定,在一些细节的实现和性能优化上可能会更加紧密和稳定。PySide6 在内存管理方面相对较为优化,特别是在一些较新版本的 Qt 特性和工具集成上,PySide6 更可能会得到官方的支持。
另一方面,PyQt6 在稳定性和成熟度上具有一定优势,因为它已经存在多年并广泛应用于众多项目中。然而,由于 PyQt6 是第三方维护的库,可能会出现更新与官方 Qt 版本不完全同步的情况,尤其是在新的功能推出时。
1.2.2 API 差异与兼容性
虽然 PySide6 和 PyQt6 的 API 在大多数情况下是兼容的,但在一些细节上可能会有所不同。例如,PySide6 对 Qt 的 C++ API 有更高的兼容性,且在某些模块中(如信号与槽机制)提供了更灵活的实现方式。而 PyQt6 则可能在一些地方对 API 的实现更为严格。
对于初学者来说,这些差异并不会影响到他们开发应用程序的基本操作。然而,对于需要精细控制的开发者,理解这些差异将有助于在项目中做出更适合的选择。
1.3 总结:选择的自由与责任
正如我们在开篇提到的“选择的自由和责任并行而至”,无论选择 PySide6 还是 PyQt6,开发者都需要根据自身的需求作出合适的决定。PySide6 提供了更加灵活的许可证和官方支持,是闭源项目的优选,而 PyQt6 在稳定性和成熟度上更为突出,适合开源项目。
第二章: 在 VS Code 中使用 PySide6 与 PyQt6
2.1 VS Code 的优势与配置
VS Code 是一款轻量级、开源的代码编辑器,以其高度可定制性和强大的扩展性而广受欢迎。它不仅支持多种编程语言的开发,还通过插件和扩展支持 Python 开发。使用 VS Code 开发 PySide6 或 PyQt6 项目,能够大大提升开发效率。
2.1.1 安装与配置 Python 扩展
要开始使用 PySide6 或 PyQt6,你首先需要安装 VS Code 的 Python 扩展。在 VS Code 中安装 Python 扩展后,你可以方便地创建、运行、调试 Python 程序,并享受代码补全和语法高亮等功能。
安装步骤如下:
- 打开 VS Code,进入扩展市场。
- 搜索并安装 “Python” 扩展。
- 配置 Python 解释器,确保使用你想要的环境(例如虚拟环境)。
2.1.2 安装 PySide6 和 PyQt6
安装好 Python 扩展后,可以通过 pip 安装 PySide6 或 PyQt6。以下是安装命令:
- 安装 PySide6:
pip install PySide6 - 安装 PyQt6:
pip install PyQt6
通过 VS Code 配置好 Python 环境后,你可以开始编写 PySide6 或 PyQt6 的代码。对于开发者来说,VS Code 提供了与这些库的良好集成,特别是对于 UI 设计的支持。
2.1.3 VS Code 调试功能
VS Code 的调试功能非常强大,你可以在 PySide6 或 PyQt6 项目中设置断点,查看变量的值,并逐步执行代码。这对于调试复杂的事件驱动应用程序非常有帮助。
第三章: PySide6 与 PyQt6 的共存与管理
3.1 同时安装的可能性与管理
如果你的电脑上同时安装了 PySide6 和 PyQt6,理论上它们是可以共存的,因为它们的模块命名空间不同。不过,在同一个项目中混用这两者并不推荐。为了避免冲突,建议使用虚拟环境来管理不同项目的依赖,这样每个项目都可以独立管理自己的 Python 库版本。
3.1.1 使用虚拟环境管理不同的库
虚拟环境能够帮助你在不同项目中使用不同版本的 PySide6 或 PyQt6,避免出现依赖冲突。例如,使用 venv 或 conda 创建虚拟环境,将每个项目的依赖与其他项目隔离开。
3.1.2 安装与配置虚拟环境
在 VS Code 中,你可以很方便地创建和管理虚拟环境:
- 在终端中创建虚拟环境:
python -m venv myenv - 激活虚拟环境:
- Windows:
myenv\Scripts\activate - macOS/Linux:
source myenv/bin/activate
- Windows:
- 安装 PySide6 或 PyQt6:
或pip install PySide6pip install PyQt6
3.2 结论:两者的选择与共存
无论你选择 PySide6 还是 PyQt6,都可以利用它们强大的功能来开发跨平台应用。选择的自由与责任并行而至,最终的决定应该基于项目的许可证需求和长期的支持考虑。通过合理配置虚拟环境,你也可以方便地在不同项目中使用它们。
第四章: 如果要互换 PySide6 与 PyQt6,代码该如何修改
在实际的开发过程中,可能会遇到需要将一个基于 PySide6 或 PyQt6 的项目从一个库切换到另一个库的情况。这种转换可能是由于许可证的原因(例如,PySide6 更适用于闭源商业项目)或者是出于对性能优化或社区支持的需求变更。无论出于什么原因,了解如何在这两个库之间转换是非常重要的。毕竟,技术的世界里,灵活性和适应能力是最宝贵的财富之一。
4.1 代码修改的基本原则
在 PySide6 和 PyQt6 之间互换时,尽管这两个库有许多相似之处,但它们之间的主要差异通常表现在模块的命名方式、API 调用的细节、信号槽机制等方面。因此,进行代码转换时,应该遵循以下几个基本原则:
- 模块名称的更改:
- PySide6 和 PyQt6 使用不同的命名空间。你需要将 PySide6 的模块导入语句替换为 PyQt6 对应的模块导入语句,反之亦然。
- 信号与槽的实现:
- 在信号和槽的连接方式上,PySide6 与 PyQt6 也有所不同。虽然它们本质上都是基于 Qt 的信号与槽机制,但 PySide6 更加灵活,允许你在没有明确定义槽签名的情况下连接信号和槽。
- 特定函数的差异:
- 由于两个库之间可能存在一些底层实现上的差异,有些 PySide6 中的函数在 PyQt6 中可能不存在,或者它们的参数和返回值可能有所不同。
4.1.1 模块导入的差异
最显而易见的变化是模块导入方式的不同。下面是一些常见模块的导入方式对比:
| 功能 | PySide6 导入方式 | PyQt6 导入方式 |
|---|---|---|
| QtCore | from PySide6.QtCore import * |
from PyQt6.QtCore import * |
| QtWidgets | from PySide6.QtWidgets import * |
from PyQt6.QtWidgets import * |
| QtGui | from PySide6.QtGui import * |
from PyQt6.QtGui import * |
| QMainWindow | from PySide6.QtWidgets import QMainWindow |
from PyQt6.QtWidgets import QMainWindow |
| QIcon | from PySide6.QtGui import QIcon |
from PyQt6.QtGui import QIcon |
从表格可以看到,PySide6 和 PyQt6 使用不同的命名空间和模块结构,因此你需要在代码中修改这些导入语句。
4.1.2 信号与槽机制的差异
PySide6 和 PyQt6 的信号与槽机制非常相似,但在某些方面有些许不同。在 PySide6 中,信号与槽的连接相对灵活,不要求在信号与槽之间的连接时明确指定槽函数的参数类型,而在 PyQt6 中,连接时需要明确指定槽函数的签名。
示例:信号与槽连接
PySide6 示例:
from PySide6.QtWidgets import QApplication, QPushButton
from PySide6.QtCore import Signal
def on_button_clicked():
print("Button clicked!")
app = QApplication([])
button = QPushButton("Click Me")
button.clicked.connect(on_button_clicked)
button.show()
app.exec()
PyQt6 示例:
from PyQt6.QtWidgets import QApplication, QPushButton
from PyQt6.QtCore import pyqtSignal
def on_button_clicked():
print("Button clicked!")
app = QApplication([])
button = QPushButton("Click Me")
button.clicked.connect(on_button_clicked)
button.show()
app.exec()
在这个例子中,Signal 和 pyqtSignal 之间的差异就是 PySide6 和 PyQt6 在信号的实现上的细微差别。PySide6 使用 Signal 来定义信号,而 PyQt6 使用 pyqtSignal。如果在 PySide6 项目中使用了自定义信号,那么你需要将 Signal 替换为 pyqtSignal,反之亦然。
4.1.3 其他差异:参数和函数名
尽管 PySide6 和 PyQt6 的功能相似,但在某些特定的函数和参数上,它们可能会有所不同。比如,某些 Qt 函数在 PySide6 和 PyQt6 中的命名方式可能会略有不同,尤其是在涉及低层次 Qt 类时。
示例:QIcon 构造函数
PySide6 示例:
from PySide6.QtGui import QIcon
icon = QIcon("icon.png")
PyQt6 示例:
from PyQt6.QtGui import QIcon
icon = QIcon("icon.png")
虽然这个示例看起来相似,但对于更复杂的 Qt 类,差异可能更加明显。你需要逐一检查文档,确保在切换过程中不会遗漏某些特定的函数参数或调用方式。
4.2 代码修改的步骤
如果你想将一个已经使用了 PySide6 的项目转换为 PyQt6,或者相反,以下是推荐的修改步骤:
4.2.1 步骤一:替换导入语句
首先,替换项目中所有的库导入语句,将 PySide6 的导入改为 PyQt6 的导入,反之亦然。
4.2.2 步骤二:调整信号与槽的连接方式
检查所有信号和槽的连接,特别是使用了自定义信号的地方。你需要确保使用正确的信号类(Signal vs. pyqtSignal)和连接方式。
4.2.3 步骤三:修改函数签名和参数
逐步检查函数调用,特别是底层的 Qt API 调用,确保 PySide6 和 PyQt6 中没有不兼容的地方。如果有的话,你需要做出相应调整。
4.2.4 步骤四:测试和调试
完成代码的修改后,你需要通过测试和调试来确保修改后的项目在新库中可以正常运行。利用 VS Code 等工具进行逐步调试,确保每个功能模块都能够正常执行。
4.3 总结
虽然 PySide6 和 PyQt6 在功能上有很多相似之处,但它们在细节上的差异意味着,如果你打算在这两个库之间切换,你需要修改导入语句、信号与槽的连接方式以及可能的函数签名。通过遵循上述步骤,你可以相对容易地实现 PySide6 和 PyQt6 之间的代码转换,进而根据需求在两者之间切换。正如任何一项技术决策,互换 PySide6 和 PyQt6 也需要做出理性分析,考虑代码的可维护性和长期使用的影响

浙公网安备 33010602011771号