v2.8.0: Add project directory support, improve dependency resolution, and fix syntax injection
- Added direct project directory drag-and-drop support with automatic root workspace and requirements.txt detection - Added smart entry script prioritization and interactive selection dialog for multi-script projects - Expanded AST dependency analysis across the entire project workspace to capture sub-package imports - Implemented local module and resource whitelisting to prevent unintended pip installations of local packages - Expanded PyPI mappings and Auto-Hooks rules for C extensions and dynamic libraries (PyCryptodome, NaCl, pynput, etc.) - Added automatic search path injection (`--paths` for PyInstaller and `PYTHONPATH` for Nuitka) for sub-directory entries - Improved `requirements.txt` parser to safely handle inline comments and environment markers - Added cross-hierarchy import detection and workspace configuration tips for standalone scripts - Fixed SyntaxError caused by console pause code injection preceding `from __future__` statements - Fixed TypeError crash caused by `os.walk` iteration variable shadowing the global translation function Update QUICKSTART.md、README.MD...
This commit is contained in:
1 parent
1f24757a71
commit
448dbdbbf3
29 files changed
+2391
-369
No files matched your search
+25
-3
@@ -2,13 +2,30 @@
|
||||
|
||||
QPyPack 项目的所有重要变更都将记录在此文件中。
|
||||
|
||||
本日志格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/) 规范,
|
||||
且本项目严格遵循 [语义化版本 (Semantic Versioning)](https://semver.org/lang/zh-CN/) 规范。
|
||||
|
||||
[English Version](./CHANGELOG_EN.md) | **中文**
|
||||
|
||||
---
|
||||
|
||||
## [2.8.0] - 2026-08-31
|
||||
|
||||
### 新增
|
||||
- 支持直接拖入项目文件夹,自动识别工作区路径并关联根目录 `requirements.txt`。
|
||||
- 增加多入口脚本匹配机制,并在检测到多个候选入口文件时提供选择对话框供用户指定。
|
||||
- 增加跨层级模块引用检测,在单独载入脚本引用上级目录模块时输出工作区配置与项目导入建议。
|
||||
|
||||
### 变更
|
||||
- 扩展 AST 依赖分析范围至整个项目工作区,提升对子模块内部依赖的识别能力。
|
||||
- 引入本地模块与附加资源白名单机制,避免将项目内部模块识别为 PyPI 依赖并执行 pip 安装。
|
||||
- 扩充默认包名映射表与 Auto-Hooks 规则库,为 `pycryptodome`、`nacl`、`soundfile`、`pynput`、`keyring`、`pydantic_core` 等库补充自动收录参数。
|
||||
- 调整构建搜索路径配置,自动为 PyInstaller 传递 `--paths`(包含工作区与 `src` 目录)并为 Nuitka 设置 `PYTHONPATH`。
|
||||
- 调整 `requirements.txt` 解析逻辑,支持处理行内注释(`#`)及环境标记(`;`)等语法。
|
||||
|
||||
### 修复
|
||||
- 修复控制台暂停代码插入位置位于 `from __future__` 语句之前导致的 `SyntaxError` 语法错误。
|
||||
- 修复 `os.walk` 迭代变量名冲突覆盖全局翻译函数引发的 `TypeError: 'list' object is not callable` 异常。
|
||||
|
||||
---
|
||||
|
||||
### [2.7.14] - 2026-08-26
|
||||
|
||||
#### 修复
|
||||
@@ -451,7 +468,12 @@ QPyPack 项目的所有重要变更都将记录在此文件中。
|
||||
|
||||
---
|
||||
|
||||
本项目向以下规范靠拢。
|
||||
[Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/) 规范,
|
||||
[语义化版本 (Semantic Versioning)](https://semver.org/lang/zh-CN/) 规范。
|
||||
|
||||
## 📄 License
|
||||
---
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
Licensed under the [GNU General Public License v3.0](LICENSE).
|
||||
+22
-3
@@ -2,13 +2,30 @@
|
||||
|
||||
All notable changes to the **QPyPack** project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
**English** | [中文版](./CHANGELOG.md)
|
||||
|
||||
---
|
||||
|
||||
## [2.8.0] - 2026-08-31
|
||||
|
||||
### Added
|
||||
- Direct project directory drag-and-drop support, automatically recognizing workspace paths and associating the root `requirements.txt`.
|
||||
- Multi-entry script matching mechanism with an entry selection dialog when multiple candidate entry files are detected.
|
||||
- Cross-hierarchy module reference detection, providing workspace configuration and project import suggestions in the log when a standalone script references parent modules.
|
||||
|
||||
### Changed
|
||||
- Expanded the AST dependency analysis scope across the entire project workspace, improving detection of internal submodules and dynamic dependencies.
|
||||
- Introduced a local module and additional resource whitelist mechanism to prevent project-internal packages from being misidentified as PyPI dependencies during pip install.
|
||||
- Expanded the default package mapping table and Auto-Hooks rules to add automatic collection parameters for `pycryptodome`, `nacl`, `soundfile`, `pynput`, `keyring`, `pydantic_core`, and other libraries.
|
||||
- Updated build search path configurations to automatically supply `--paths` (including workspace and `src` directories) to PyInstaller and configure `PYTHONPATH` for Nuitka.
|
||||
- Refined `requirements.txt` parsing logic to support inline comments (`#`) and environment markers (`;`).
|
||||
|
||||
### Fixed
|
||||
- Fixed a `SyntaxError` caused by console pause code injection occurring prior to `from __future__` statements.
|
||||
- Fixed a `TypeError: 'list' object is not callable` crash caused by an `os.walk` iteration variable shadowing the global translation function.
|
||||
|
||||
---
|
||||
|
||||
### [2.7.14] - 2026-08-26
|
||||
|
||||
#### Fixed
|
||||
@@ -447,6 +464,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* **Custom PIP Mirror Support**: Added PIP mirror configuration defaulting to Tsinghua University mirrors, with immediate UI application and `QSettings` persistence.
|
||||
* **Unified Build Logic**: Virtual environment initialization and dependency resolution now strictly adhere to user-configured PIP mirrors.
|
||||
|
||||
---
|
||||
Strictly following the **[Keep a Changelog 1.0.0](https://keepachangelog.com/en/1.0.0/)** and **[Semantic Versioning 2.0.0](https://semver.org/)** specifications.
|
||||
---
|
||||
|
||||
## 📄 License
|
||||
|
||||
+267
-47
@@ -1,90 +1,310 @@
|
||||
# ⚡ QPyPack 快速入门指南 (Quick Start Guide)
|
||||
# ⚡ QPyPack 快速入门指南 | Quick Start Guide
|
||||
|
||||
欢迎使用 **QPyPack**!本指南将带你在 3 分钟内掌握 QPyPack 的核心功能与打包流程,轻松将 Python 脚本转换为可独立运行的原生可执行程序 (`.exe` / macOS App / Linux 二进制)。
|
||||
<p align="center">
|
||||
<a href="#-简体中文">简体中文</a> | <a href="#-english">English</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 📥 第一步:安装与启动 QPyPack
|
||||
## 🇨🇳 简体中文
|
||||
|
||||
你可以根据使用习惯选择以下任意一种方式启动 QPyPack:
|
||||
欢迎使用 **QPyPack**!本指南将带你在 3 分钟内掌握 QPyPack 的核心功能与打包流程,轻松将 Python 脚本或复杂工程项目转换为独立运行的原生可执行程序 (`.exe` / macOS `.app` / Linux 二进制)。
|
||||
|
||||
### 方式 A:通过 `pip` 安装(推荐开发者使用)
|
||||
---
|
||||
|
||||
### 📥 第一步:安装与启动
|
||||
|
||||
你可以根据使用习惯选择以下任意一种方式获取并运行 QPyPack:
|
||||
|
||||
#### 方式 A:通过包管理器安装(推荐开发者)
|
||||
|
||||
在已配置 Python (>= 3.8) 的终端中执行:
|
||||
|
||||
```bash
|
||||
# 安装 QPyPack
|
||||
# 1. 在线安装
|
||||
pip install qpypack
|
||||
|
||||
# 在命令行直接启动 GUI 界面
|
||||
# 启动 GUI 界面
|
||||
qpypack
|
||||
```
|
||||
|
||||
### 方式 B:使用预编译独立免安装版(适合无 Python 环境用户)
|
||||
*若使用现代包管理器(免全局安装,隔离运行):*
|
||||
```bash
|
||||
# 使用 pipx 隔离运行
|
||||
pipx run qpypack
|
||||
|
||||
前往 [GitHub Releases](https://github.com/Qwejay/QPyPack/releases) 下载对应系统的可执行文件:
|
||||
* **Windows**: 下载 `QPyPack.exe` 双击即可运行。
|
||||
* **macOS / Linux**: 下载对应的预编译应用程序或可执行文件。
|
||||
# 或使用 uv 极速启动
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
*离线安装(使用 Releases 提供的 Wheel 包):*
|
||||
```bash
|
||||
pip install qpypack-2.8.0-py3-none-any.whl
|
||||
```
|
||||
|
||||
#### 方式 B:下载 GitHub Releases 预编译包(适合无 Python 环境用户)
|
||||
|
||||
前往 [GitHub Releases 页面](https://github.com/Qwejay/QPyPack/releases) 直接下载对应系统的预编译发布包(以下以QPyPack-2.8.0为例):
|
||||
|
||||
| 操作系统 / 架构 | 发布包文件名 | 版本说明 |
|
||||
| :--- | :--- | :--- |
|
||||
| **Windows (x64)** | `QPyPack-2.8.0-windows-x64-Standalone.zip` | **单文件独立版**(解压即为一个干净的单个 `.exe` 文件) |
|
||||
| **Windows (x64)** | `QPyPack-2.8.0-windows-x64-Portable.zip` | **便携目录版**(包含完整依赖目录,秒级启动,无临时解压延迟) |
|
||||
| **Linux (x64)** | `QPyPack-2.8.0-linux-x64-Standalone.tar.gz` | **单文件独立版**(解压即用单可执行文件) |
|
||||
| **Linux (x64)** | `QPyPack-2.8.0-linux-x64-Portable.tar.gz` | **便携目录版**(包含完整运行库目录) |
|
||||
| **macOS (Apple Silicon)** | `QPyPack-2.8.0-macos-arm64.dmg` | **原生 DMG 镜像**(原生适配 Apple Silicon M1/M2/M3/M4 系列芯片) |
|
||||
| **全平台 Python** | `qpypack-2.8.0-py3-none-any.whl` | **离线 Wheel 包**(适用于内网或离线环境 `pip install`) |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 第二步:标准打包 5 步曲
|
||||
|
||||
启动 QPyPack 后,整体打包过程仅需简单点击几下:
|
||||
### 🎯 第二步:标准打包 5 步流程
|
||||
|
||||
```
|
||||
[1. 拖入源码] ➔ [2. 选择引擎与模式] ➔ [3. 依赖与环境] ➔ [4. 点击构建] ➔ [5. 获取产物]
|
||||
[1. 载入文件/工程] ➔ [2. 引擎与模式] ➔ [3. 附加数据文件] ➔ [4. 依赖与环境] ➔ [5. 构建与产物]
|
||||
```
|
||||
|
||||
### 1. 拖入 Python 源码
|
||||
* 将你的主入口文件(如 `main.py` 或 `app.pyw`)**直接拖拽**到主界面的虚线拖拽区域内。
|
||||
* 软件将自动解析程序名称、自动比对脚本图标,并初始化工作空间。
|
||||
#### 1. 载入脚本文件或项目工程文件夹
|
||||
* **单脚本打包**:将主入口脚本(如 `main.py` 或 `app.pyw`)**直接拖入**主界面的虚线区域。
|
||||
* **多层级复杂工程打包**:直接将**整个项目总文件夹**拖入主界面,QPyPack 会自动锁定工作区根目录、识别根目录 `requirements.txt`,并自动匹配主入口脚本(若有多个候选入口会弹出点选框)。
|
||||
|
||||
### 2. 选择打包引擎与模式
|
||||
切换到 **「构建设置」** 面板:
|
||||
#### 2. 选择构建引擎与模式
|
||||
进入 **「构建设置」** 面板:
|
||||
* **构建引擎 (Engine)**:
|
||||
* **PyInstaller**:打包速度极快,零配置,适合快速交付与常规应用。
|
||||
* **Nuitka**:将 Python 编译为 C/C++ 二进制,体积更小、运行更快且具有极强的抗反编译保护(无需手动配置 C 编译器,QPyPack 会自动托管)。
|
||||
* **PyInstaller**:构建速度快(通常 10~60 秒),零外部 C 编译器依赖,生态兼容性好。
|
||||
* **Nuitka**:将 Python 直接编译为 C/C++ 原生二进制,体积更小、启动更快,具备极强的代码防反编译保护(未检测到本地 C 编译器时,QPyPack 会自动下载托管 MinGW-w64)。
|
||||
* **打包模式 (Packaging Mode)**:
|
||||
* **单文件 (`--onefile`)**:生成单个 `.exe` / 可执行文件,干净便携。
|
||||
* **精简模式 (Lite Mode)**:动态排除开发/测试等冗余依赖,有效缩减产物体积(若失败可随时切回兼容模式)。
|
||||
* **单文件 (`--onefile`)**:生成单个独立的 `.exe` / 可执行文件,便携干净。
|
||||
* **文件夹 (`--onedir`)**:生成包含主程序与 `_internal` 依赖文件夹的目录,适合包含大量静态资源的复杂应用。
|
||||
* **精简模式 (Lite Mode)**:自动剔除未引用的重型模块并开启 LTO 链接优化,大幅压缩体积(若特殊动态导入报错,切回「兼容模式」即可)。
|
||||
|
||||
### 3. 配置 Python 环境与依赖
|
||||
* **Python 解释器**:软件会自动检测系统默认 Python。若本地未安装 Python,可点击「查看 Python」一键自动下载并配置环境。
|
||||
* **虚拟环境 (推荐勾选)**:勾选「使用虚拟环境」可隔离本地污染;勾选「保留虚拟环境」可在多次重新打包时复用 `.qpypack_venv`,极大缩短后续构建时间。
|
||||
* **依赖扫描**:勾选「分析依赖 (原生 AST)」,QPyPack 会静态扫描源码中的隐式 `import`,彻底解决运行时 `ModuleNotFoundError`。
|
||||
#### 3. 配置附加资源(静态文件 / 资产)
|
||||
如果你的程序需要读取额外的外部数据(图片、网页静态资源、配置文件、解密密钥等):
|
||||
* 切换到 **【构建设置】 $\rightarrow$ 【附加资源】**;
|
||||
* 点击「添加文件」或「添加目录」,也可直接把资源文件夹(如 `assets/`、`static/`)拖入列表;
|
||||
* 支持双击修改打包后的相对存放路径。
|
||||
|
||||
### 4. 开始构建
|
||||
* 点击底部的 **「开始构建」** 按钮。
|
||||
* 可以在界面下方的 **「执行日誌」** 查看实时编译状态,支持切换「精简模式/详细模式」。
|
||||
#### 4. 依赖管理与环境隔离
|
||||
* **Python 解释器**:自动检测系统 Python;若未安装,点击「查看 Python」可一键自动下载安装。
|
||||
* **虚拟环境沙盒 (推荐)**:勾选「使用虚拟环境」可隔离环境污染;勾选「保留虚拟环境」可在重复构建时复用 `.qpypack_venv` 缓存,大幅提速后续打包。
|
||||
* **智能依赖分析 (AST)**:勾选「分析依赖 (原生 AST)」,系统会自动穿透扫描源码中的隐式依赖,并自动处理包名映射(如 `Crypto` $\to$ `pycryptodome`、`cv2` $\to$ `opencv-python`),同时智能排除本地工程模块,防止 pip 误装报错。
|
||||
|
||||
### 5. 获取打包产物
|
||||
* 构建成功后,点击 **「打开目录」** 即可直接跳转到生成的应用程序目录。
|
||||
#### 5. 开始构建与获取产物
|
||||
* 点击主界面底部的 **「开始构建」** 按钮;
|
||||
* 展开下方的 **「执行日志」** 可实时查看编译输出;
|
||||
* 构建成功后,点击 **「打开目录」** 即可直接定位到生成的成品程序。
|
||||
|
||||
---
|
||||
|
||||
## 💡 典型应用场景配置推荐
|
||||
### 💡 典型应用场景配置推荐
|
||||
|
||||
| 场景需求 | 推荐引擎 | 打包模式 | 关键设置 |
|
||||
| 场景需求 | 推荐引擎 | 推荐形态 | 关键设置与建议 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **日常小工具 / 快速脚本** | PyInstaller | 单文件 (`--onefile`) + 精简模式 | 自动提取图标 |
|
||||
| **商业软件 / 防反编译源码** | Nuitka | 单文件 (`--onefile`) + 兼容模式 | 使用虚拟环境 + 保留虚拟环境 |
|
||||
| **大型 GUI 框架 (PySide/PyQt)** | PyInstaller / Nuitka | 文件夹 (`--onedir`) | 勾选「分析依赖 (原生 AST)」 |
|
||||
| **Playwright / 爬虫自动化** | PyInstaller | 单文件 (`--onefile`) | 自动拦截 Playwright 浏览器依赖 |
|
||||
| **日常小工具 / 自动化脚本** | PyInstaller | 单文件 (`--onefile`) | 自动提取图标 + 勾选「精简模式」 |
|
||||
| **Web 服务 (FastAPI / Flask)** | PyInstaller / Nuitka | 文件夹 (`--onedir`) | 拖入项目总文件夹 + 附加资源添加 `static/`、`templates/` |
|
||||
| **商业软件 / 核心算法保护** | Nuitka | 单文件 (`--onefile`) | 勾选「使用虚拟环境」+ 开启数字签名 |
|
||||
| **大型桌面 GUI (PySide6 / PyQt)** | PyInstaller / Nuitka | 文件夹 (`--onedir`) | 勾选「分析依赖 (原生 AST)」+ 开启「精简模式」剔除未使用子模块 |
|
||||
| **加解密 / 复杂底层 C 扩展** | PyInstaller | 文件夹 (`--onedir`) | 保持「兼容模式」确保 C 扩展 `.pyd` 完整收录 |
|
||||
|
||||
---
|
||||
|
||||
## ❓ 常见问题排查 (FAQ)
|
||||
### 📋 开发者最佳实践:资源文件路径寻址规范
|
||||
|
||||
### Q1: 打包完成后运行报错 `ModuleNotFoundError`?
|
||||
* **解决方法**:前往【构建设置】->【依赖管理】,勾选 **「分析依赖 (原生 AST)」** 或 **「扫描整个文件夹」**;也可在「隐式导入 (hidden-imports)」中手动填入缺失的包名(如 `pandas, PIL`)。
|
||||
在单文件模式(`--onefile`)下,打包后的数据文件会在运行时临时解压至特定沙盒目录。请在源码中统一采用以下标准函数获取资源绝对路径,避免路径报错:
|
||||
|
||||
### Q2: 精简模式 (Lite Mode) 构建失败怎么办?
|
||||
* **解决方法**:精简模式会剔除不常用的动态依赖。如果构建失败,请在【构建设置】中将打包模式切回 **「兼容模式 (Compatibility Mode)」** 重新构建即可。
|
||||
```python
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
### Q3: 使用 Nuitka 引擎提示缺少 C 编译器?
|
||||
* **解决方法**:不用担心!QPyPack 内置编译器智能托管,未检测到 MSVC 或 GCC 时会自动为你下载并配置 MinGW-w64 编译器工具链,全程无需手动干预。
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""获取程序运行时资源的绝对路径(兼容本地开发、PyInstaller 与 Nuitka)"""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# PyInstaller 单文件临时解压目录
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Nuitka 二进制执行目录
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# 本地开发调试目录
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
|
||||
# 使用示例:
|
||||
# logo_path = get_asset_path("assets/logo.png")
|
||||
# config_path = get_asset_path("config/settings.json")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
📖 **需要更详细的配置与高级优化说明?** 请参阅完整版 [README.md](README.md)。
|
||||
### ❓ 常见问题排查 (FAQ)
|
||||
|
||||
#### Q1: 打包后运行报错 `ModuleNotFoundError: No module named 'xxx'`?
|
||||
* **原因**:程序中使用了动态反射导入(如 `importlib`)或某些包的子模块未被静态检测到。
|
||||
* **解决办法**:在【构建设置】 $\rightarrow$ 【依赖管理】中的「隐式导入 (hidden-imports)」填入缺失的包名(逗号分隔);或在【附加资源】中将该本地源码包目录添加进去。
|
||||
|
||||
#### Q2: 静态资源(图片/配置文件)在单文件打包后读不到?
|
||||
* **原因**:源码中使用了 `open("assets/config.json")` 相对当前工作目录寻址,而单文件解压到了临时路径。
|
||||
* **解决办法**:参考上方 [资源文件路径寻址规范](#-开发者最佳实践资源文件路径寻址规范),使用 `sys._MEIPASS` 兼容代码。对于大型 Web/数据项目,优先推荐使用 **文件夹模式 (`--onedir`)**。
|
||||
|
||||
#### Q3: Windows 下运行打包出的程序,瞬间弹出几百个窗口死机?
|
||||
* **原因**:项目中使用了 `multiprocessing` 多进程,但在 Windows 上未加保护。
|
||||
* **解决办法**:在主入口文件的 `if __name__ == '__main__':` 块内第一行调用 `multiprocessing.freeze_support()`。
|
||||
|
||||
#### Q4: Nuitka 提示缺少 C/C++ 编译器?
|
||||
* **解决办法**:完全无需手动配置环境变量!QPyPack 内置编译器自动托管机制。未检测到 MSVC 或 GCC 时,Nuitka 会自动下载并配置 MinGW-w64 编译器。
|
||||
|
||||
---
|
||||
|
||||
## 🇬🇧 English
|
||||
|
||||
Welcome to **QPyPack**! This guide helps you master the core features and packaging workflow of QPyPack in 3 minutes, transforming Python scripts and complex projects into standalone native executables (`.exe` / macOS `.app` / Linux binaries).
|
||||
|
||||
---
|
||||
|
||||
### 📥 Step 1: Installation & Launch
|
||||
|
||||
Choose any of the following methods to obtain and launch QPyPack:
|
||||
|
||||
#### Method A: Install via Package Manager (Recommended for Developers)
|
||||
|
||||
Run in a terminal with Python (>= 3.8):
|
||||
|
||||
```bash
|
||||
# 1. Install via pip
|
||||
pip install qpypack
|
||||
|
||||
# Launch the GUI directly from command line
|
||||
qpypack
|
||||
```
|
||||
|
||||
*Run in an isolated environment via modern package managers (Zero global install):*
|
||||
```bash
|
||||
# Using pipx
|
||||
pipx run qpypack
|
||||
|
||||
# Or using uv for ultra-fast startup
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
*Offline installation (using the Release Wheel):*
|
||||
```bash
|
||||
pip install qpypack-2.8.0-py3-none-any.whl
|
||||
```
|
||||
|
||||
#### Method B: Standalone Pre-built Releases (For Users without Python)
|
||||
|
||||
Download the release asset for your platform from the [GitHub Releases page](https://github.com/Qwejay/QPyPack/releases):
|
||||
|
||||
| OS / Architecture | Release Asset | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| **Windows (x64)** | `QPyPack-2.8.0-windows-x64-Standalone.zip` | **Standalone Single-File** (Extracts to a single standalone `.exe`) |
|
||||
| **Windows (x64)** | `QPyPack-2.8.0-windows-x64-Portable.zip` | **Portable Directory** (Full runtime directory, fast launch, zero extraction overhead) |
|
||||
| **Linux (x64)** | `QPyPack-2.8.0-linux-x64-Standalone.tar.gz` | **Standalone Single-File** (Single executable binary) |
|
||||
| **Linux (x64)** | `QPyPack-2.8.0-linux-x64-Portable.tar.gz` | **Portable Directory** (Extracted folder with full runtime libraries) |
|
||||
| **macOS (Apple Silicon)** | `QPyPack-2.8.0-macos-arm64.dmg` | **Native DMG Image** (Native installer for Apple Silicon M1/M2/M3/M4 Macs) |
|
||||
| **Universal Python** | `qpypack-2.8.0-py3-none-any.whl` | **Offline Wheel** (For offline environments via `pip install`) |
|
||||
|
||||
---
|
||||
|
||||
### 🎯 Step 2: Standard 5-Step Packaging Workflow
|
||||
|
||||
```
|
||||
[1. Load Script/Project] ➔ [2. Engine & Mode] ➔ [3. Data Files] ➔ [4. Dependencies] ➔ [5. Build & Output]
|
||||
```
|
||||
|
||||
#### 1. Load Python Script or Project Directory
|
||||
* **Single Script**: Drag and drop your main entry file (e.g., `main.py` or `app.pyw`) **directly into the drop zone**.
|
||||
* **Multi-directory Projects**: Drag and drop the **entire project root folder** into the drop zone. QPyPack will automatically lock the workspace root, link the root `requirements.txt`, and match the entry point (prompting an entry selection dialog if multiple candidates exist).
|
||||
|
||||
#### 2. Choose Packaging Engine & Mode
|
||||
Navigate to the **"Build Settings"** panel:
|
||||
* **Build Engine**:
|
||||
* **PyInstaller**: Fast compilation (typically 10–60 seconds), zero compiler dependencies, and extensive ecosystem compatibility.
|
||||
* **Nuitka**: Compiles Python directly into native C/C++ binaries, offering smaller output size, faster startup, and deep anti-decompilation protection (MinGW-w64 toolchain is automatically provisioned if no C compiler is detected).
|
||||
* **Packaging Mode**:
|
||||
* **Single-File (`--onefile`)**: Bundles everything into a single standalone executable file.
|
||||
* **Directory Mode (`--onedir`)**: Generates an application folder containing the executable and `_internal` dependency tree, ideal for media/web apps with heavy assets.
|
||||
* **Lite Mode**: Automatically excludes redundant testing/development modules and enables Link-Time Optimization (`--lto=yes`) to reduce binary footprint.
|
||||
|
||||
#### 3. Configure Additional Resources (Static Assets)
|
||||
If your application requires external data files (images, web templates, configs, encryption keys, etc.):
|
||||
* Switch to **"Build Settings" $\rightarrow$ "Resources"**;
|
||||
* Click "Add File" or "Add Dir", or drag resource directories (e.g., `assets/`, `static/`) directly into the list;
|
||||
* Double-click any item to customize its relative bundle target path.
|
||||
|
||||
#### 4. Dependency Management & Environment Isolation
|
||||
* **Python Interpreter**: Automatically detects system Python. Click "View Python" to download and configure one if none is found.
|
||||
* **Virtual Environment Sandbox (Recommended)**: Check "Use Virtual Environment" to prevent global package pollution. Check "Keep Local Venv" to reuse `.qpypack_venv` cache across builds.
|
||||
* **AST Dependency Analysis**: Check "Analyze Dependencies (AST)". QPyPack recursively parses Abstract Syntax Trees to detect hidden imports, applies package name mappings (e.g., `Crypto` $\to$ `pycryptodome`, `cv2` $\to$ `opencv-python`), and isolates local modules from triggering redundant pip downloads.
|
||||
|
||||
#### 5. Build and Obtain Binaries
|
||||
* Click the **"Start Build"** button at the bottom;
|
||||
* Expand the **"Execution Log"** to inspect real-time compiler outputs (switchable between Concise and Detailed modes);
|
||||
* Upon completion, click **"Open Directory"** to navigate directly to your generated executable.
|
||||
|
||||
---
|
||||
|
||||
### 💡 Recommended Configurations by Project Type
|
||||
|
||||
| Scenario | Recommended Engine | Packaging Mode | Key Settings & Tips |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **CLI Tools / Quick Scripts** | PyInstaller | Single-File (`--onefile`) | Auto Extract Icon + Enable Lite Mode |
|
||||
| **Web Services (FastAPI / Flask)** | PyInstaller / Nuitka | Directory (`--onedir`) | Drag project root folder + Add `static/` & `templates/` to Resources |
|
||||
| **Commercial Software / IP Protection** | Nuitka | Single-File (`--onefile`) | Use Virtual Environment + Enable Smart Code Signing |
|
||||
| **Desktop GUI (PySide6 / PyQt)** | PyInstaller / Nuitka | Directory (`--onedir`) | Enable AST Analysis + Lite Mode to prune unused submodules |
|
||||
| **C-Extensions / Cryptography** | PyInstaller | Directory (`--onedir`) | Use Compatibility Mode to ensure all binary `.pyd` files are retained |
|
||||
|
||||
---
|
||||
|
||||
### 📋 Developer Best Practices: Runtime Asset Path Resolution
|
||||
|
||||
In Single-File mode (`--onefile`), bundled data files are extracted to a temporary sandbox directory at runtime. Use the following standard helper function to resolve asset paths across development, PyInstaller, and Nuitka:
|
||||
|
||||
```python
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""Resolve absolute asset path across Dev, PyInstaller, and Nuitka."""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# PyInstaller temporary extraction directory
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Nuitka native binary directory
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# Local development directory
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
|
||||
# Usage Example:
|
||||
# logo_path = get_asset_path("assets/logo.png")
|
||||
# config_path = get_asset_path("config/settings.json")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ❓ Troubleshooting & FAQ
|
||||
|
||||
#### Q1: Runtime error `ModuleNotFoundError: No module named 'xxx'` after building?
|
||||
* **Cause**: Dynamic reflection imports (e.g., `importlib`) or submodules were missed during static analysis.
|
||||
* **Solution**: In "Build Settings" $\rightarrow$ "Dependencies", add the missing package names to "Hidden Imports", or add the local package directory to "Additional Resources".
|
||||
|
||||
#### Q2: Static asset files (images/configs) cannot be found in `--onefile` mode?
|
||||
* **Cause**: The code uses relative paths like `open("assets/config.json")`, which evaluates relative to `os.getcwd()` rather than the extracted bundle directory.
|
||||
* **Solution**: Follow the [Runtime Asset Path Resolution](#-developer-best-practices-runtime-asset-path-resolution) pattern using `sys._MEIPASS`. For complex web/data apps, prefer **Directory Mode (`--onedir`)**.
|
||||
|
||||
#### Q3: Windows executable spawns hundreds of subprocess windows until crashing?
|
||||
* **Cause**: The application uses `multiprocessing` without freeze protection on Windows.
|
||||
* **Solution**: Call `multiprocessing.freeze_support()` as the very first line inside `if __name__ == '__main__':` in your entry script.
|
||||
|
||||
#### Q4: Nuitka reports missing C/C++ compiler?
|
||||
* **Solution**: No manual environment variable setup is required! QPyPack features automated compiler provisioning. If MSVC or GCC is absent, Nuitka will automatically download and manage a compatible MinGW-w64 toolchain.
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
📖 <b>Need more advanced optimizations and configuration details?</b><br>
|
||||
Please consult the comprehensive <a href="README.md">README.md</a> or visit our <a href="https://github.com/Qwejay/QPyPack">GitHub Repository</a>.
|
||||
</p>
|
||||
+149
-25
@@ -14,70 +14,194 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Ein plattformübergreifendes GUI-Tool zur Paketierung von Python-Anwendungen basierend auf PyInstaller & Nuitka</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack ist ein visuelles GUI-Tool zur Vereinfachung des Build-Prozesses von Python-Anwendungen. Es integriert PyInstaller und Nuitka nahtlos und wandelt komplexe Befehlszeilenparameter in eine intuitive grafische Benutzeroberfläche um.
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>Modernes, einsatzbereites plattformübergreifendes GUI-Tool zur Paketierung von Python-Anwendungen</strong><br>
|
||||
<sub>Angetrieben von PyInstaller und Nuitka, mit visueller Konfiguration, statischer Abhängigkeitsanalyse und automatisiertem Build-Workflow.</sub>
|
||||
</p>
|
||||
|
||||
## 📌 Projektübersicht (Overview)
|
||||
|
||||
**QPyPack** ist ein plattformübergreifendes grafisches Paketierungstool für Python-Entwickler. Durch die nahtlose Integration der beiden Haupt-Engines **PyInstaller** (Bytecode-Bündelung) und **Nuitka** (native C/C++-Kompilierung) werden komplexe Compiler-Toolchains, implizite Abhängigkeitsanalysen, Sandbox-Isolation und Ressourcenextraktion in einer intuitiven Benutzeroberfläche abstrahiert.
|
||||
|
||||
Egal ob Sie einfache Automatisierungsskripte oder komplexe Desktop- und Serveranwendungen (mit PySide6/PyQt, Playwright, CustomTkinter, FastAPI etc.) verteilen möchten: QPyPack bietet einen stabilen, hochgradig reproduzierbaren Build-Prozess unter Windows, macOS und Linux.
|
||||
|
||||
---
|
||||
|
||||
## 📷 Screenshots
|
||||
## 📸 Screenshots
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="Hauptfenster (Englisch)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="Hauptfenster (Chinesisch)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="Engine & Umgebung" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="Abhängigkeitsverwaltung" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="Optimierung & Signierung" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="Über & Diagnose" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Hauptfunktionen
|
||||
## 🛠️ Hauptfunktionen & Architektur
|
||||
|
||||
* 📥 **Drag & Drop** : Ziehen Sie `.py`- oder `.pyw`-Skripte direkt in das Anwendungsfenster.
|
||||
* 🎨 **Automatische Icon-Erkennung** : Erkennt automatisch Bilddateien im Quellordner und wandelt diese um.
|
||||
* 🛡️ **Virtuelle Umgebung (Sandbox)** : Erstellt automatisch eine isolierte Umgebung zur Minimierung der Ausgabegröße.
|
||||
* 🔍 **Abhängigkeitsanalyse** : Erkennt `requirements.txt` und führt statische AST-Code-Analysen für verdeckte Importe durch.
|
||||
* ⚙️ **Dual-Engine-Unterstützung** : Wechseln Sie nahtlos zwischen PyInstaller und Nuitka.
|
||||
* 📝 **App-Metadaten-Injektion** : Fügen Sie Versionsnummern und Beschreibungen direkt in die Binärdatei ein.
|
||||
### 1. Dual-Engine-Kompilierung & Binäroptimierung
|
||||
* **Nahtloser Wechsel zwischen zwei Engines**:
|
||||
* **PyInstaller**: Schnelle Build-Zeiten, keine C-Compiler-Abhängigkeit, hervorragende Kompatibilität.
|
||||
* **Nuitka**: Übersetzt Python-Code direkt in native C/C++-Binärdateien für hohe Ausführungsgeschwindigkeit, starken Schutz gegen Reverse-Engineering und kompakte Ausgabegröße.
|
||||
* **LTO-Linkzeitoptimierung & Modulbereinigung**: Unterstützt `--lto=yes` im Lite-Modus; ungenutzte schwere Qt-Submodule (z. B. `WebEngine`, `3D`, `Quick`) werden automatisch erkannt und entfernt, um Dateigrößen-Overhead zu vermeiden.
|
||||
* **Flexible Ausgabeformate**: Unterstützt **Einzeldatei- (`--onefile`)** und **Verzeichnis-Modus (`--onedir`)** sowie benutzerdefinierte interne Ressourcenpfade (`--contents-directory`).
|
||||
|
||||
### 2. Statische Codeanalyse & Topologieschutz
|
||||
* **Natives rekursives AST-Scanning**: Analysiert abstrakte Syntaxbäume (AST) direkt in Python, um explizite und implizite Importe (Hidden Imports) ohne Programmausführung zu erfassen.
|
||||
* **Intelligentes Paket-Mapping**: Enthält Zuordnungstabellen für gängige Import- und PyPI-Paketnamen (z. B. `cv2` $\to$ `opencv-python`, `PIL` $\to$ `pillow`, `win32com` $\to$ `pywin32`), modular erweiterbar.
|
||||
* **Automatische Backport-Isolation**: Erkennt und blockiert veraltete Backport-Bibliotheken, die mit modernen Standardbibliotheken kollidieren (z. B. `pathlib` oder `typing` unter Python 3.10+).
|
||||
|
||||
### 3. Automatisiertes Umgebungsmanagement & Selbstheilung
|
||||
* **Automatische C/C++-Compiler-Verwaltung**: Erkennt lokale MSVC-, Clang- (LLVM) und GCC-Installationen. Falls kein nativer Compiler vorhanden ist, lädt Nuitka automatisch eine MinGW-w64-Toolchain herunter.
|
||||
* **Lebenszyklus virtueller Umgebungen**: Unterstützt isolierte Sandkästen sowie wiederverwendbare geteilte virtuelle Umgebungen mit Bereinigungsfunktion.
|
||||
* **Ressourcenüberwachung & Fehlerselbstheilung**:
|
||||
* Bewertet vor dem Build RAM und Festplattenspeicher und passt die Thread-Parallelität (Adaptive Concurrency) an.
|
||||
* Fängt Speicherengpässe (`ZstdError` / OOM) ab und wiederholt den Build im Single-Thread-Modus.
|
||||
* Umgeht Dateisperren durch Antivirenprogramme oder Cloud-Synchronisationsdienste.
|
||||
|
||||
### 4. Codesignatur & Projekt-Voreinstellungen
|
||||
* **Intelligente digitale Signatur**: Signiert Windows-Binärdateien automatisch via Authenticode (unterstützt Signtool und PowerShell mit RFC 3161 Zeitstempeln) sowie macOS `codesign`.
|
||||
* **Zertifikat-Suite**: Integrierter Generator für selbstsignierte `.pfx`-Zertifikate und Unterstützung für kommerzielle Zertifikate.
|
||||
* **Projekt-Presets (Import/Export)**: Speichert alle Build-Parameter, Ressourcenlisten und Mappings in portable `.qpypack`-Dateien.
|
||||
|
||||
### 5. Benutzererlebnis & Lokalisierung
|
||||
* **Intuitive Drag & Drop-Bedienung**: Automatisches Auslesen von Modul-Metadaten (`__version__`, `__author__`, App-Titel) und Zuweisung von Programmsymbolen.
|
||||
* **Google Material Vektor-UI**: Skaliert verlustfrei auf High-DPI/4K-Monitoren. Enthält Übersetzungen für 17 Sprachen (Deutsch, Englisch, Chinesisch, Japanisch, Koreanisch, Französisch, Spanisch etc.).
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Schnellstart
|
||||
## 📊 Engine-Vergleich (PyInstaller vs. Nuitka)
|
||||
|
||||
| Kriterium | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **Funktionsweise** | Bündelt Python-Interpreter + Bytecode (`.pyc`) | Kompiliert Python-Code zu nativen C/C++-Binärdateien |
|
||||
| **Build-Geschwindigkeit** | Sehr schnell (typisch 10 – 60 s) | Moderat bis langsam (erfordert C++-Kompilierung) |
|
||||
| **Compiler-Bedarf** | Keiner | Erforderlich (MSVC / GCC / Clang / MinGW-w64) |
|
||||
| **Code-Schutz** | Basis (über Dekompilierer einsehbar) | Extrem hoch (Maschinencode, hoher Reverse-Engineering-Schutz) |
|
||||
| **Ausführungsleistung** | Standard Python-Geschwindigkeit | Sehr schneller Start, optimierte Schleifen/Berechnungen |
|
||||
| **Empfohlen für** | Schnelles Prototyping, interne Tools, dynamische Skripte | Kommerzielle Distribution, Schutz geistigen Eigentums, kompakte Größe |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Schnellstart (Quick Start)
|
||||
|
||||
> 💡 **Erste Schritte?** Konsultieren Sie unsere [**📖 Kurzanleitung (QUICKSTART.md)**](../../QUICKSTART.md) für Schritt-für-Schritt-Anweisungen und empfohlene Konfigurationen.
|
||||
|
||||
### Methode 1: Installation über pip / pipx (Empfohlen)
|
||||
|
||||
Voraussetzung: Python >= 3.8
|
||||
|
||||
```bash
|
||||
# Über pip installieren
|
||||
# Installation via pip
|
||||
pip install qpypack
|
||||
|
||||
# Anwendung starten
|
||||
qpypack
|
||||
```
|
||||
|
||||
Alternativ können Sie vorkompilierte Dateien von der [GitHub Release-Seite](https://github.com/Qwejay/QPyPack/releases) herunterladen.
|
||||
*Mit modernen Paketmanagern:*
|
||||
```bash
|
||||
# Isoliert über pipx
|
||||
pipx run qpypack
|
||||
|
||||
# Ultraschnell über uv
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### Methode 2: Vorkompilierte Binärdateien
|
||||
|
||||
Ohne lokale Python-Installation können Sie direkt kompilierte Binärdateien für Windows, macOS oder Linux herunterladen:
|
||||
|
||||
👉 [**Vorkompilierte Versionen herunterladen (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Pfadauflösung für Ressourcen (`sys._MEIPASS`)
|
||||
|
||||
Im Einzeldatei-Modus (`--onefile`) werden statische Dateien (Bilder, Konfigurationen, Modelle) zur Laufzeit temporär entpackt. Verwenden Sie folgendes Standardmuster zur Pfadauflösung:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""Ermittelt den absoluten Pfad zu gepackten Ressourcen."""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# PyInstaller temporäres Extraktionsverzeichnis
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Nuitka natives Binärverzeichnis
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# Lokale Entwicklungsumgebung
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 Änderungsprotokoll (Changelog)
|
||||
|
||||
Die vollständige Versionshistorie finden Sie in [CHANGELOG.md](CHANGELOG.md) oder auf der [GitHub Releases-Seite](https://github.com/Qwejay/QPyPack/releases).
|
||||
Ausführliche Versionshinweise und behobene Fehler finden Sie in [CHANGELOG.md](../../CHANGELOG.md).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Lizenz
|
||||
## 💖 Mitwirken & Sponsoring
|
||||
|
||||
Lizenziert unter der [GNU General Public License v3.0](LICENSE).
|
||||
QPyPack ist ein Open-Source-Projekt. Wenn Ihnen das Tool bei Ihrer Arbeit geholfen hat, freuen wir uns über Ihre Unterstützung:
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
- 🌟 **Star vergeben**: Schenken Sie uns einen Stern auf [GitHub](https://github.com/Qwejay/QPyPack).
|
||||
- 🐛 **Feedback & Fehlerberichte**: Erstellen Sie ein [Issue auf GitHub](https://github.com/Qwejay/QPyPack/issues).
|
||||
- ⚡ **Sponsoring**: Unterstützen Sie das Projekt auf [Afdian (爱发电)](https://www.ifdian.net/a/qwejay) (WeChat / Alipay).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Lizenz (License)
|
||||
|
||||
Lizenziert unter der [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Urheberrecht an kompilierten Binärdateien**:
|
||||
> Die Rechte an Ihren mit QPyPack erstellten Anwendungen **verbleiben vollständig bei Ihnen**. Die GPL-3.0-Lizenz von QPyPack überträgt sich nicht auf Ihre kompilierten Programme.
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+149
-25
@@ -14,70 +14,194 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Herramienta GUI multiplataforma para empaquetar aplicaciones Python basada en PyInstaller y Nuitka</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack es una herramienta gráfica diseñada para simplificar el empaquetado de aplicaciones Python. Integra los motores PyInstaller y Nuitka, transformando comandos de consola en una interfaz intuitiva.
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>Herramienta GUI moderna y lista para usar para empaquetar aplicaciones Python multiplataforma</strong><br>
|
||||
<sub>Impulsada por los motores PyInstaller y Nuitka, con configuración visual, análisis estático de dependencias y flujo de compilación automatizado.</sub>
|
||||
</p>
|
||||
|
||||
## 📌 Visión general del proyecto (Overview)
|
||||
|
||||
**QPyPack** es una herramienta gráfica multiplataforma diseñada para desarrolladores de Python. Al integrar de manera nativa los motores **PyInstaller** (empaquetado de bytecode) y **Nuitka** (compilación nativa C/C++), simplifica las cadenas de compilación complejas, el análisis de dependencias implícitas, el aislamiento de entornos y la recolección de recursos en una interfaz intuitiva.
|
||||
|
||||
Ya sea para distribuir scripts ligeros de automatización o aplicaciones de escritorio y servidor con dependencias complejas (como PySide6/PyQt, Playwright, CustomTkinter, FastAPI, etc.), QPyPack ofrece una experiencia de compilación estable, reproducible y con alta tasa de éxito en Windows, macOS y Linux.
|
||||
|
||||
---
|
||||
|
||||
## 📷 Capturas de pantalla (Screenshots)
|
||||
## 📸 Capturas de pantalla (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="Interfaz principal (Inglés)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="Interfaz principal (Chino)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="Motor y Entorno" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="Gestión de dependencias" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="Optimización y Firma" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="Acerca de y Diagnósticos" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Características principales
|
||||
## 🛠️ Arquitectura y características principales
|
||||
|
||||
* 📥 **Arrastrar y Soltar** : Arrastre archivos `.py` o `.pyw` directamente a la ventana.
|
||||
* 🎨 **Detección de icono automática** : Convierte y previsualiza iconos del directorio fuente.
|
||||
* 🛡️ **Aislamiento en entorno virtual** : Crea entornos virtuales automáticamente para reducir el tamaño final.
|
||||
* 🔍 **Análisis de dependencias** : Lectura de `requirements.txt` y análisis estático de código AST para importaciones ocultas.
|
||||
* ⚙️ **Conmutación de motor doble** : Cambie libremente entre PyInstaller y Nuitka.
|
||||
* 📝 **Inyección de metadatos** : Configure la versión, autor y descripción directamente desde la interfaz.
|
||||
### 1. Motor dual de compilación y optimización binaria
|
||||
* **Conmutación fluida entre motores**:
|
||||
* **PyInstaller**: Compilación rápida, sin dependencias de compilador C, excelente compatibilidad con el ecosistema.
|
||||
* **Nuitka**: Traduce código Python a binarios C/C++ nativos para un rendimiento superior, máxima protección contra ingeniería inversa y tamaño reducido.
|
||||
* **Optimización LTO y poda de submódulos**: Soporte para optimización en tiempo de enlace (`--lto=yes`) en modo Lite. Detección y exclusión automática de submódulos Qt pesados no utilizados (WebEngine, 3D, Quick, etc.) para evitar el sobrepeso binario.
|
||||
* **Formatos de distribución flexibles**: Compatible con modo de **Archivo único (`--onefile`)** y modo **Directorio (`--onedir`)**, con personalización del directorio interno de dependencias (`--contents-directory`).
|
||||
|
||||
### 2. Análisis estático y protección de dependencias
|
||||
* **Escaneo AST recursivo nativo**: Analizador estático de árbol de sintaxis abstracta (AST) en Python puro que descubre importaciones explícitas e implícitas sin ejecutar el código.
|
||||
* **Mapeo inteligente de paquetes**: Tabla de correspondencia integrada entre nombres de importación y paquetes PyPI (ej. `cv2` $\to$ `opencv-python`, `PIL` $\to$ `pillow`, `win32com` $\to$ `pywin32`), modular y extensible.
|
||||
* **Aislamiento dinámico de bibliotecas obsoletas (Backport Isolation)**: Detecta y bloquea paquetes de retrocompatibilidad que entren en conflicto con la biblioteca estándar moderna (ej. aislando `pathlib` o `typing` en Python 3.10+).
|
||||
|
||||
### 3. Gestión automatizada del entorno y autorreparación
|
||||
* **Aprovisionamiento automático de compiladores C/C++**: Detecta entornos locales MSVC, Clang (LLVM) y GCC. Si no hay compilador nativo, Nuitka descarga y gestiona automáticamente una cadena MinGW-w64.
|
||||
* **Gestión del ciclo de vida de entornos virtuales**: Admite sandboxes aislados y entornos virtuales compartidos, con utilidad de limpieza integrada.
|
||||
* **Gestión adaptativa de recursos y autorrecuperación**:
|
||||
* Evalúa RAM y espacio en disco antes de compilar, ajustando la concurrencia de hilos (Adaptive Concurrency).
|
||||
* Captura errores de memoria saturada (`ZstdError` / OOM) y reintenta automáticamente en modo monohilo de bajo consumo.
|
||||
* Evita bloqueos exclusivos de archivos temporales causados por antivirus o servicios de sincronización en la nube.
|
||||
|
||||
### 4. Firma de código y preajustes de proyecto
|
||||
* **Firma digital inteligente**: Aplica firmas digitales Authenticode automáticamente a binarios de Windows (compatible con Signtool y PowerShell con sellado de tiempo RFC 3161) y firma en tiempo de ejecución `codesign` en macOS.
|
||||
* **Suite de certificados**: Generador integrado de certificados autofirmados (`.pfx`) y soporte para certificados comerciales.
|
||||
* **Importación/Exportación de preajustes**: Guarda todos los parámetros de compilación, recursos y reglas en archivos `.qpypack` compartibles.
|
||||
|
||||
### 5. Experiencia de usuario e internacionalización (i18n)
|
||||
* **Arrastrar y soltar fluido**: Al soltar un script Python, extrae automáticamente los metadatos (`__version__`, `__author__`, nombre de la app), deduce el punto de entrada y mapea el icono de la aplicación.
|
||||
* **Interfaz vectorial con soporte HiDPI**: Construida con iconos vectoriales Google Material SVG, con escalado perfecto en pantallas 4K. Traducida a 17 idiomas (español, inglés, chino, japonés, coreano, alemán, francés, etc.).
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Inicio rápido
|
||||
## 📊 Comparativa de motores (PyInstaller vs. Nuitka)
|
||||
|
||||
| Criterio | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **Principio** | Empaqueta intérprete de Python + bytecode (`.pyc`) | Compila código Python a binarios C/C++ nativos |
|
||||
| **Velocidad de compilación** | Muy rápida (típicamente 10 – 60 s) | Más lenta (requiere generación de código C++ y optimización) |
|
||||
| **Compilador C/C++** | No requerido | Requerido (gestión automática de MSVC / GCC / Clang / MinGW-w64) |
|
||||
| **Nivel de protección** | Básico (código recuperable mediante descompiladores) | Extremadamente alto (código máquina, alta resistencia a ingeniería inversa) |
|
||||
| **Rendimiento de ejecución**| Velocidad estándar de Python | Inicio más rápido, bucles y computación optimizados |
|
||||
| **Recomendado para** | Prototipado rápido, herramientas internas, proyectos dinámicos | Software comercial, protección de algoritmos, optimización de tamaño |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Inicio rápido (Quick Start)
|
||||
|
||||
> 💡 **¿Primera vez usando QPyPack?** Consulte nuestra [**📖 Guía de inicio rápido (QUICKSTART.md)**](../../QUICKSTART.md) para un tutorial detallado y configuraciones recomendadas.
|
||||
|
||||
### Método 1: Instalación mediante pip / pipx (Recomendado)
|
||||
|
||||
Requiere Python >= 3.8:
|
||||
|
||||
```bash
|
||||
# Instalar a través de pip
|
||||
pip install qpypack
|
||||
|
||||
# Iniciar la aplicación
|
||||
# Iniciar la interfaz gráfica
|
||||
qpypack
|
||||
```
|
||||
|
||||
Descargue ejecutables precompilados directamente en la página de [Releases de GitHub](https://github.com/Qwejay/QPyPack/releases).
|
||||
*Con gestores de paquetes modernos:*
|
||||
```bash
|
||||
# Ejecutar aislado con pipx
|
||||
pipx run qpypack
|
||||
|
||||
# Inicio ultrarrápido con uv
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### Método 2: Versión binaria precompilada independiente
|
||||
|
||||
Sin necesidad de configurar Python localmente, descargue los ejecutables compilados directamente para su sistema operativo:
|
||||
|
||||
👉 [**Descargar versiones precompiladas (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Resolución de rutas de recursos (`sys._MEIPASS`)
|
||||
|
||||
En modo de archivo único (`--onefile`), los recursos estáticos (imágenes, configuraciones, modelos) se extraen temporalmente al ejecutarse. Utilice el siguiente patrón estándar para resolver rutas:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""Obtiene la ruta absoluta a recursos empaquetados."""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# Directorio de extracción temporal de PyInstaller
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Directorio de ejecución binaria de Nuitka
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# Entorno de desarrollo local
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 Historial de cambios (Changelog)
|
||||
|
||||
Para ver las notas de versión completas, consulte [CHANGELOG.md](CHANGELOG.md) o la página de [Releases de GitHub](https://github.com/Qwejay/QPyPack/releases).
|
||||
Consulte [CHANGELOG.md](../../CHANGELOG.md) para notas de versión detalladas y corrección de errores.
|
||||
|
||||
---
|
||||
|
||||
## 📄 Licencia
|
||||
## 💖 Contribuciones y patrocinio
|
||||
|
||||
Licenciado bajo la [GNU General Public License v3.0](LICENSE).
|
||||
QPyPack es un proyecto de código abierto mantenido en mi tiempo libre. Si le ha sido de utilidad, agradecemos su apoyo voluntario:
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
- 🌟 **Estrella en GitHub**: Dele una estrella al repositorio en [GitHub](https://github.com/Qwejay/QPyPack).
|
||||
- 🐛 **Reportes y sugerencias**: Envíe incidencias a través de [GitHub Issues](https://github.com/Qwejay/QPyPack/issues).
|
||||
- ⚡ **Patrocinar**: Apoye al autor a través de [Afdian (爱发电)](https://www.ifdian.net/a/qwejay) (WeChat Pay / Alipay).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Licencia (License)
|
||||
|
||||
Este proyecto está licenciado bajo la [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Derechos de autor sobre los binarios generados**:
|
||||
> La propiedad intelectual y los términos de licencia de las aplicaciones creadas con QPyPack **pertenecen en su totalidad al usuario**. La licencia GPL-3.0 de QPyPack no impone restricciones sobre su software compilado.
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+149
-25
@@ -14,49 +14,121 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Un outil GUI multiplateforme pour empaqueter des applications Python basé sur PyInstaller & Nuitka</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack est un outil graphique conçu pour simplifier le processus d'empaquetage des applications Python. Il intègre de manière transparente deux moteurs de compilation majeurs—PyInstaller et Nuitka—convertissant les arguments complexes en ligne de commande en une interface visuelle intuitive.
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>Outil GUI moderne et prêt à l'emploi pour empaqueter des applications Python multiplateformes</strong><br>
|
||||
<sub>Propulsé par PyInstaller et Nuitka, offrant configuration visuelle, analyse statique des dépendances et flux de compilation automatisé.</sub>
|
||||
</p>
|
||||
|
||||
## 📌 Présentation du projet (Overview)
|
||||
|
||||
**QPyPack** est un outil graphique multiplateforme conçu pour les développeurs Python. En intégrant de manière transparente les deux moteurs majeurs **PyInstaller** (empaquetage de bytecode) et **Nuitka** (compilation C/C++ native), QPyPack abstrait les chaînes d'outils complexes, l'analyse des dépendances implicites, l'isolation d'environnements et la collecte de ressources dans une interface de bureau intuitive.
|
||||
|
||||
Qu'il s'agisse de distribuer de simples scripts d'automatisation ou des applications complexes (avec PySide6/PyQt, Playwright, CustomTkinter, FastAPI, etc.), QPyPack garantit une expérience de compilation fiable, reproductible et à haut taux de succès.
|
||||
|
||||
---
|
||||
|
||||
## 📷 Captures d'écran (Screenshots)
|
||||
## 📸 Captures d'écran (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="Interface principale (Anglais)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="Interface principale (Chinois)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="Moteur et Environnement" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="Gestion des dépendances" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="Optimisation et Signature" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="À propos et Diagnostics" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Fonctionnalités principales
|
||||
## 🛠️ Architecture & Fonctionnalités clés
|
||||
|
||||
* 📥 **Glisser-déposer intuitif** : Glissez simplement vos fichiers `.py` ou `.pyw` dans l'application.
|
||||
* 🎨 **Détection d'icône automatique** : Conversion et aperçu automatique des icônes présentes dans le dossier source.
|
||||
* 🛡️ **Bac à sable d'environnement virtuel** : Crée un environnement virtuel isolé pour réduire la taille de l'exécutable final.
|
||||
* 🔍 **Analyse des dépendances** : Détection de `requirements.txt` et analyse statique du code (AST) pour inclure les dépendances implicites.
|
||||
* ⚙️ **Commutation de moteur double** : Basculez facilement entre PyInstaller et Nuitka.
|
||||
* 📝 **Injection de métadonnées** : Configurez la version, l'auteur et la description directement depuis l'interface (Windows PE & macOS Info.plist).
|
||||
### 1. Double moteur de compilation & Optimisation binaire
|
||||
* **Basculement transparent entre les moteurs** :
|
||||
* **PyInstaller** : Compilation rapide, sans dépendance de compilateur C, excellente compatibilité.
|
||||
* **Nuitka** : Traduit le code Python en binaires C/C++ natifs pour des performances accrues, une forte protection contre la rétro-ingénierie et une taille d'exécutable réduite.
|
||||
* **Optimisation LTO & Élagage de sous-modules** : Support de l'optimisation à l'édition des liens (`--lto=yes`) en mode Lite. Détection et exclusion automatique des sous-modules Qt lourds non utilisés (WebEngine, 3D, Quick, etc.) pour éviter l'alourdissement du binaire.
|
||||
* **Formats de distribution flexibles** : Prise en charge des modes **Fichier unique (`--onefile`)** et **Dossier (`--onedir`)**, avec personnalisation du dossier interne des ressources (`--contents-directory`).
|
||||
|
||||
### 2. Analyse statique & Protection des dépendances
|
||||
* **Scan AST récursif natif** : Analyseur statique d'arbre syntaxique abstrait (AST) en pur Python, découvrant les dépendances explicites et implicites sans exécuter le code.
|
||||
* **Système de mappage intelligent** : Table de correspondance intégrée entre noms d'import et paquets PyPI (ex. `cv2` $\to$ `opencv-python`, `PIL` $\to$ `pillow`, `win32com` $\to$ `pywin32`), entièrement personnalisable.
|
||||
* **Isolation dynamique des bibliothèques obsolètes (Backport Isolation)** : Détecte et neutralise automatiquement les bibliothèques de rétrocompatibilité en conflit avec la bibliothèque standard moderne (ex. `pathlib` ou `typing` sous Python 3.10+).
|
||||
|
||||
### 3. Gestion automatisée des environnements & Auto-récupération
|
||||
* **Provisionnement automatique des compilateurs C/C++** : Détecte automatiquement MSVC, Clang (LLVM) et GCC. En l'absence de compilateur local, Nuitka télécharge et gère automatiquement une chaîne d'outils MinGW-w64.
|
||||
* **Gestion du cycle de vie des environnements virtuels** : Prise en charge des bacs à sable isolés et des environnements virtuels partagés, avec outil de nettoyage intégré.
|
||||
* **Gestion adaptative des ressources & Résilience** :
|
||||
* Évalue la mémoire vive et l'espace disque avant la compilation pour ajuster automatiquement le nombre de cœurs CPU (Adaptive Concurrency).
|
||||
* Récupère automatiquement les erreurs de mémoire saturée (`ZstdError` / OOM) en relançant la compilation en mode basse mémoire mono-thread.
|
||||
* Contourne les verrouillages temporaires de fichiers causés par les antivirus ou les services de synchronisation cloud.
|
||||
|
||||
### 4. Signature de code & Préréglages de projet
|
||||
* **Signature numérique intelligente** : Applique automatiquement les signatures numériques Authenticode aux binaires Windows (compatible Signtool et PowerShell avec horodatage RFC 3161) et signature runtime `codesign` sous macOS.
|
||||
* **Suite de certificats** : Outil intégré de génération de certificats auto-signés (`.pfx`) et prise en charge des certificats commerciaux.
|
||||
* **Exportation / Importation de préréglages** : Sauvegarde tous les paramètres de compilation, listes de ressources et règles dans des fichiers portables `.qpypack`.
|
||||
|
||||
### 5. Expérience utilisateur moderne & i18n
|
||||
* **Glisser-déposer intuitif** : Déposer un script Python analyse automatiquement les métadonnées (`__version__`, `__author__`, nom de l'application), déduit le point d'entrée et associe l'icône correspondante.
|
||||
* **Interface vectorielle avec support HiDPI** : Entièrement conçue avec les icônes vectorielles Google Material SVG pour un rendu net sur écrans 4K/Haute résolution. Traduite en 17 langues (français, anglais, chinois, japonais, coréen, allemand, espagnol, etc.).
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Démarrage rapide
|
||||
## 📊 Comparatif des moteurs (PyInstaller vs. Nuitka)
|
||||
|
||||
| Critère | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **Principe** | Bündle l'interpréteur Python + bytecode (`.pyc`) | Compile le code Python en binaires C/C++ natifs |
|
||||
| **Vitesse de compilation** | Très rapide (généralement 10 – 60 s) | Plus lente (génération de code C++ et optimisations) |
|
||||
| **Compilateur C/C++** | Non requis | Requis (MSVC / GCC / Clang / MinGW-w64 géré) |
|
||||
| **Protection du code** | Basique (décompilation possible) | Très élevée (code machine compilé, résistant à l'ingénierie inverse) |
|
||||
| **Performances d'exécution** | Vitesse standard de Python | Démarrage plus rapide, boucles et calculs intensifs optimisés |
|
||||
| **Recommandé pour** | Prototypage rapide, outils internes, projets à imports dynamiques | Logiciels commerciaux, protection d'algorithmes, optimisation de taille |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Démarrage rapide (Quick Start)
|
||||
|
||||
> 💡 **Première utilisation ?** Consultez notre [**📖 Guide de démarrage rapide (QUICKSTART.md)**](../../QUICKSTART.md) pour un pas-à-pas détaillé et les configurations recommandées.
|
||||
|
||||
### Méthode 1 : Installation via pip / pipx (Recommandée)
|
||||
|
||||
Nécessite Python >= 3.8 :
|
||||
|
||||
```bash
|
||||
# Installer via pip
|
||||
@@ -66,18 +138,70 @@ pip install qpypack
|
||||
qpypack
|
||||
```
|
||||
|
||||
Ou téléchargez les exécutables autonomes directement sur la page des [GitHub Releases](https://github.com/Qwejay/QPyPack/releases).
|
||||
*Avec les gestionnaires de paquets modernes :*
|
||||
```bash
|
||||
# Exécuter de manière isolée avec pipx
|
||||
pipx run qpypack
|
||||
|
||||
# Lancement ultra-rapide avec uv
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### Méthode 2 : Version binaire autonome précompilée
|
||||
|
||||
Sans configuration préalable de Python, téléchargez directement les exécutables précompilés pour votre système :
|
||||
|
||||
👉 [**Télécharger la version précompilée (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📅 Notes de version (Changelog)
|
||||
## 📋 Résolution des chemins de ressources (`sys._MEIPASS`)
|
||||
|
||||
Pour consulter l'historique complet des mises à jour, veuillez vous référer à [CHANGELOG.md](CHANGELOG.md) ou à la page des [GitHub Releases](https://github.com/Qwejay/QPyPack/releases).
|
||||
En mode fichier unique (`--onefile`), les fichiers statiques (images, configurations, modèles) sont extraits à l'exécution dans un dossier temporaire isolé. Utilisez le modèle standard suivant pour résoudre les chemins :
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""Résout le chemin absolu des ressources empaquetées."""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# Répertoire d'extraction temporaire PyInstaller
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Répertoire d'exécution binaire Nuitka
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# Environnement de développement local
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📄 Licence
|
||||
## 📅 Historique des versions (Changelog)
|
||||
|
||||
Distribué sous la licence [GNU General Public License v3.0](LICENSE).
|
||||
Pour consulter les notes de version détaillées et les corrections de bugs, référez-vous à [CHANGELOG.md](../../CHANGELOG.md).
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
---
|
||||
|
||||
## 💖 Contribution & Sponsoring
|
||||
|
||||
QPyPack est un projet open-source développé sur mon temps personnel. Si cet outil vous est utile, vous pouvez soutenir sa maintenance continue :
|
||||
|
||||
- 🌟 **Étoile GitHub** : Donnez une étoile au projet sur [GitHub](https://github.com/Qwejay/QPyPack).
|
||||
- 🐛 **Retours & Suggestions** : Soumettez vos rapports de bugs sur [GitHub Issues](https://github.com/Qwejay/QPyPack/issues).
|
||||
- ⚡ **Soutien financier** : Contribuez via [Afdian (爱发电)](https://www.ifdian.net/a/qwejay) (WeChat Pay / Alipay).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Licence (License)
|
||||
|
||||
Ce projet est distribué sous licence [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Propriété des binaires générés** :
|
||||
> Les droits de propriété intellectuelle et les licences des applications créées avec QPyPack **appartiennent intégralement à l'utilisateur**. La licence GPL-3.0 de QPyPack n'impose aucune contrainte sur vos binaires finaux.
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+149
-23
@@ -14,70 +14,196 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>PyInstaller と Nuitka をベースにしたクロスプラットフォーム Python パッケージング GUI ツール</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack は、Python アプリケーションのパッケージング手順を簡素化するために設計された GUI ツールです。PyInstaller と Nuitka の 2 大コンパイルエンジンを高度に統合し、複雑な CLI コマンドライン引数を直感的な GUI 操作に変換します。
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>モダンで使いやすいクロスプラットフォーム対応 Python アプリケーションパッケージング GUI ツール</strong><br>
|
||||
<sub>PyInstaller と Nuitka のデュアルエンジンを搭載し、視覚的な設定、静的依存関係解析、自動ビルドパイプラインを提供</sub>
|
||||
</p>
|
||||
|
||||
## 📌 プロジェクト概要 (Overview)
|
||||
|
||||
**QPyPack** は、Python 開発者のために設計されたクロスプラットフォームのグラフィカルパッケージングツールです。**PyInstaller**(インタープリタおよびバイトコード同梱)と **Nuitka**(C/C++ ネイティブコンパイル)の 2 大コアエンジンを高度に統合し、複雑な低レイヤコンパイル引数、暗黙の依存関係解析、環境分離、リソース収集プロセスを直感的な GUI に集約しました。
|
||||
|
||||
シンプルな自動化スクリプトの配布から、大規模な依存関係(PySide6 / PyQt、Playwright、CustomTkinter、FastAPI など)を持つデスクトップやサーバーサイドアプリまで、QPyPack は安定した高い成功率と再現性のあるビルド体験を提供します。
|
||||
|
||||
---
|
||||
|
||||
## 📷 スクリーンショット (Screenshots)
|
||||
## 📸 スクリーンショット (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="メイン画面(英語)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="メイン画面(中国語)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="エンジンと環境設定" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="依存関係管理とスキャン" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="最適化・署名・セキュリティ" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="バージョン情報と診断" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 主な機能 (Key Features)
|
||||
## 🛠️ コアアーキテクチャと機能 (Key Features)
|
||||
|
||||
* 📥 **ドラッグ&ドロップ対応**: `.py` / `.pyw` ソースファイルをウィンドウに直接ドラッグして読み込み。
|
||||
* 🎨 **アイコン自動検出**: ソースディレクトリ内の画像資産 (`icon.ico` / `logo.svg` 等) を自動検出しフォーマット変換。
|
||||
* 🛡️ **仮想環境サンドボックス**: 独立した仮想環境を自動生成し、最小限の依存関係でバイナリサイズを削減。
|
||||
* 🔍 **依存関係の自動解析**: `requirements.txt` 解析および AST 静的解析による暗黙のインポート (Hidden Imports) 補完。
|
||||
* ⚙️ **デュアルエンジン切替**: PyInstaller と Nuitka をワンクリックで切り替え。
|
||||
* 📝 **メタデータ注入**: バージョン情報や作者情報を実行ファイルプロパティに自動書き込み。
|
||||
### 1. デュアルビルドエンジンとバイナリ最適化
|
||||
* **シームレスなデュアルエンジン切替**:
|
||||
* **PyInstaller**:高速なビルド速度、外部 C コンパイラ不要、優れた互換性とエコシステムサポート。
|
||||
* **Nuitka**:Python ソースコードを直接ネイティブ C/C++ バイナリにトランスパイルし、実行パフォーマンス向上、高い難読化/耐リバースエンジニアリング性能、コンパクトなファイルサイズを実現。
|
||||
* **LTO リンク時最適化とサブモジュール削除**:軽量モード(Lite Mode)で `--lto=yes` リンク時最適化をサポート。PySide/PyQt において参照されていない重いサブモジュール(WebEngine、3D、Quick など)を自動検出して除外し、バイナリ肥大化を防止。
|
||||
* **柔軟な出力形式**:**単一ファイル形式 (`--onefile`)** と **ディレクトリ形式 (`--onedir`)** をサポートし、内部依存関係ディレクトリの指定 (`--contents-directory`) にも対応。
|
||||
|
||||
### 2. 静的解析と依存関係トポロジー保護
|
||||
* **ネイティブ AST 再帰スキャン**:純粋な Python 実装の抽象構文木(AST)静的解析エンジンを内蔵。コードを実行せずにソースコードとプロジェクトディレクトリ内のインポート関係を再帰的に解析。
|
||||
* **インテリジェントなパッケージ名マッピング**:一般的なサードパーティ製ライブラリのインポート名と PyPI パッケージ名のマッピングテーブルを内蔵(例: `cv2` $\to$ `opencv-python`、`PIL` $\to$ `pillow`、`win32com` $\to$ `pywin32`)。ユーザーによるカスタム拡張も可能。
|
||||
* **古い互換パッケージの動的隔離 (Backport Isolation)**:ターゲット Python バージョンの標準ライブラリと競合する古い Backport パッケージを自動検知して除外(例: Python 3.10+ における `pathlib` や `typing` の自動隔離)。
|
||||
|
||||
### 3. 環境の自動管理と自己修復フォールバック
|
||||
* **C/C++ コンパイラの自動プロビジョニング**:ローカルの MSVC、Clang (LLVM)、GCC 環境を自動検出。コンパイラが存在しない場合、Nuitka エンジンが互換性のある MinGW-w64 ツールチェーンを自動ダウンロードおよび管理。
|
||||
* **仮想環境ライフサイクル管理**:完全隔離の仮想環境サンドボックスおよび共有仮想環境モードをサポート。過去の無効な仮想環境の一括スキャンとクリーンアップユーティリティを搭載。
|
||||
* **適応型リソース管理とエラー自動復旧**:
|
||||
* ビルド前にディスク容量と物理メモリを評価し、メモリ不足時には並行スレッド数(Adaptive Concurrency)を自動調整。
|
||||
* メモリ割り当てオーバーフロー(OOM / ZstdError)を検知し、シングルスレッド低メモリモードで自動再試行。
|
||||
* Windows アンチウイルスソフトウェアによる中間アイコンや一時ファイルの排他ロックを自動回避。
|
||||
|
||||
### 4. コード署名とデリバリー保証
|
||||
* **スマートデジタル署名管理**:Windows ビルド生成後に Authenticode デジタル署名を自動適用(Signtool および PowerShell エンジンに対応、RFC 3161 タイムスタンプサービス統合)。macOS のワンクリック `codesign` ランタイム署名に対応。
|
||||
* **自己署名証明書スイート**:Windows 自己署名コード署名証明書(`.pfx`)生成ツールを内蔵し、商用秘密鍵証明書とパスワード設定をサポート。
|
||||
* **プロジェクト設定プリセットのインポート/エクスポート**:すべてのビルド引数、リソース一覧、マッピングルールを共有可能な `.qpypack` プリセットファイルとしてエクスポート可能。
|
||||
|
||||
### 5. クロスプラットフォーム UX
|
||||
* **ドラッグ&ドロップ対応**:Python スクリプトをドロップするだけで、モジュールのメタデータ(バージョン、作者、アプリ名)の解析、エントリーポイントの推論、アプリアイコンのマッピングを自動完了。
|
||||
* **ベクターレンダリングと多言語 i18n**:Google Material SVG ベクターアイコンを採用し、4K/高 DPI ディスプレイのスケーリングに完全対応。日本語、英語、簡体字/繁体字中国語、韓国語、ドイツ語、フランス語など 17 言語の即時切り替えをサポート。
|
||||
|
||||
---
|
||||
|
||||
## 📊 エンジン選定の比較 (PyInstaller vs. Nuitka)
|
||||
|
||||
| 比較項目 | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **パッケージング原理** | Python インタープリタとバイトコード (`.pyc`) を同梱 | Python コードをネイティブ C/C++ バイナリにコンパイル |
|
||||
| **ビルド時間** | 非常に高速(通常 10 〜 60 秒) | 比較的低速(C++ コード生成とコンパイラ最適化を伴う) |
|
||||
| **C/C++ コンパイラ依存** | 不要 | 必要(MSVC / GCC / Clang / MinGW-w64 自動ダウンロード対応) |
|
||||
| **コード保護レベル** | 基本(デコンパイラでソース復元可能) | 極めて高い(機械語バイナリ化、強固な耐解析性) |
|
||||
| **実行パフォーマンス** | 標準的な Python 実行速度 | 起動が高速、ループや計算負荷の高い処理で優位 |
|
||||
| **推奨ユースケース** | 迅速なプロトタイプ検証、社内ツール、動的インポートが多いプロジェクト | 商用配布ソフトウェア、コアアルゴリズム保護、サイズ・起動速度重視 |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ クイックスタート (Quick Start)
|
||||
|
||||
> 💡 **初めてのご利用ですか?** 詳細な手順と推奨設定については、[**📖 クイックスタートガイド (QUICKSTART.md)**](../../QUICKSTART.md) をご参照ください。
|
||||
|
||||
### 方法 1:pip / pipx によるインストール(推奨)
|
||||
|
||||
Python >= 3.8 の環境で以下を実行します:
|
||||
|
||||
```bash
|
||||
# pip によるインストール
|
||||
pip install qpypack
|
||||
|
||||
# アプリケーションの起動
|
||||
# GUI アプリケーションの起動
|
||||
qpypack
|
||||
```
|
||||
|
||||
または [GitHub Releases ページ](https://github.com/Qwejay/QPyPack/releases) からビルド済みバイナリを直接ダウンロードできます。
|
||||
*モダンなパッケージマネージャーを使用する場合(推奨):*
|
||||
```bash
|
||||
# pipx による隔離実行
|
||||
pipx run qpypack
|
||||
|
||||
# uv による高速起動
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### 方法 2:スタンドアロンビルド済みバイナリ版
|
||||
|
||||
Python 環境の事前構築を行わず、GitHub Releases ページから OS に適した実行ファイルを直接ダウンロードして利用できます:
|
||||
|
||||
👉 [**ビルド済みバイナリのダウンロード (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📋 ベストプラクティス:リソース解決パス (`sys._MEIPASS`)
|
||||
|
||||
単一ファイルモード(`--onefile`)では、同梱された静的アセット(画像、設定ファイル、モデルデータなど)は実行時にサンドボックス一時ディレクトリへ展開されます。ソースコード内では以下の標準パターンを用いて安全にパスを解決してください:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""パッケージング後のリソース絶対パスを取得"""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# PyInstaller 単一ファイルの展開ディレクトリ
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Nuitka ネイティブバイナリの実行ディレクトリ
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# ローカル開発・デバッグ環境ディレクトリ
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 更新履歴 (Changelog)
|
||||
|
||||
詳細なリリースノートおよび更新履歴については、[CHANGELOG.md](CHANGELOG.md) または [GitHub Releases ページ](https://github.com/Qwejay/QPyPack/releases) を参照してください。
|
||||
詳細なバージョン履歴、新機能、バグ修正内容については [CHANGELOG.md](../../CHANGELOG.md) をご覧ください。
|
||||
|
||||
---
|
||||
|
||||
## 💖 貢献とスポンサーシップ (Contributing & Sponsorship)
|
||||
|
||||
QPyPack はオープンソースの理念に基づいて開発・メンテナンスされています。日々の開発や業務でお役に立ちましたら、継続的な改善のためご支援をいただけますと幸いです:
|
||||
|
||||
- 🌟 **Star を付ける**:[GitHub](https://github.com/Qwejay/QPyPack) リポジトリにスターをお願いします。
|
||||
- 🐛 **フィードバックと提案**:[Issue](https://github.com/Qwejay/QPyPack/issues) からバグ報告や改善要望をお寄せください。
|
||||
- ⚡ **スポンサー**:[Afdian (爱发电)](https://www.ifdian.net/a/qwejay) より無償の寄付を受け付けています(WeChat Pay / Alipay 対応)。
|
||||
|
||||
> *注:スポンサーシップはオープンソースコミュニティへの自発的な支援であり、商用サポートや特定機能開発の義務を伴うものではありません。*
|
||||
|
||||
---
|
||||
|
||||
## 📄 ライセンス (License)
|
||||
|
||||
[GNU General Public License v3.0](LICENSE) のもとでオープンソース化されています。
|
||||
本プロジェクトは [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE) に基づいてオープンソースとして公開されています。
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
> [!IMPORTANT]
|
||||
> **ビルド成果物の著作権について**:
|
||||
> QPyPack を使用して生成された最終バイナリおよびアプリケーションの**知的財産権とライセンス形態は、完全にユーザー自身に帰属します**。QPyPack の GPL-3.0 ライセンスがビルド成果物に対して伝播することはありません。
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+150
-24
@@ -14,70 +14,196 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>PyInstaller 및 Nuitka 기반의 크로스 플랫폼 Python 애플리케이션 패키징 GUI 도구</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack은 Python 애플리케이션 패키징 프로세스를 단순화하도록 설계된 GUI 도구입니다. PyInstaller와 Nuitka를 깊이 통합하여 복잡한 CLI 명령을 직관적인 그래픽 인터페이스로 변환합니다.
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>현대적이고 즉시 사용 가능한 크로스 플랫폼 Python 애플리케이션 패키징 GUI 도구</strong><br>
|
||||
<sub>PyInstaller 및 Nuitka 듀얼 엔진을 탑재하여 시각적 구성, 정적 의존성 분석 및 자동화된 빌드 워크플로 제공</sub>
|
||||
</p>
|
||||
|
||||
## 📌 프로젝트 개요 (Overview)
|
||||
|
||||
**QPyPack**은 Python 개발자를 위해 설계된 크로스 플랫폼 그래픽 패키징 도구입니다. **PyInstaller**(인터프리터 및 바이트코드 번들링)와 **Nuitka**(C/C++ 네이티브 컴파일) 듀얼 코어 엔진을 깊이 통합하여 복잡한 컴파일 파라미터, 암시적 의존성 분석, 가상 환경 격리, 리소스 수집 프로세스를 직관적인 GUI 인터페이스로 단순화했습니다.
|
||||
|
||||
경량 자동화 스크립트 배포부터 대규모 의존성(PySide6 / PyQt, Playwright, CustomTkinter, FastAPI 등)을 포함하는 데스크톱 및 서버 애플리케이션까지, QPyPack은 높은 성공률과 재현 가능한 빌드 경험을 제공합니다.
|
||||
|
||||
---
|
||||
|
||||
## 📷 스크린샷 (Screenshots)
|
||||
## 📸 스크린샷 (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="메인 화면 (영어)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="메인 화면 (중국어)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="빌드 엔진 및 환경" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="의존성 관리 및 스캔" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="최적화, 서명 및 보안" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="정보 및 진단" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 주요 기능 (Key Features)
|
||||
## 🛠️ 핵심 아키텍처 및 주요 기능 (Key Features)
|
||||
|
||||
* 📥 **드래그 앤 드롭 지원**: 소스 파일(.py / .pyw)을 창으로 끌어다 놓아 빠르게 로드.
|
||||
* 🎨 **아이콘 자동 추출**: 디렉터리 내 아이콘 자산(`icon.ico`, `logo.svg` 등) 자동 탐지 및 포맷 변환.
|
||||
* 🛡️ **가상 환경 샌드박스**: 독립된 가상 환경을 생성하여 최소 의존성만 설치, 실행 파일 용량 최적화.
|
||||
* 🔍 **의존성 자동 분석**: `requirements.txt` 파싱 및 AST 정적 스캔을 통한 암시적 임포트(Hidden Imports) 추출.
|
||||
* ⚙️ **듀얼 엔진 스위칭**: PyInstaller와 Nuitka 간의 손쉬운 전환.
|
||||
* 📝 **메타데이터 주입**: 버전 정보, 작성자, 설명을 UI에서 직접 실행 파일 속성에 주입.
|
||||
### 1. 듀얼 빌드 엔진 및 바이너리 최적화
|
||||
* **원활한 듀얼 엔진 전환**:
|
||||
* **PyInstaller**: 빠른 빌드 속도, 외부 C 컴파일러 불필요, 광범위한 생태계 호환성 지원.
|
||||
* **Nuitka**: Python 코드를 C/C++ 바이너리로 직접 변환하여 실행 속도 향상, 강력한 역공학 방지, 컴팩트한 용량 제공.
|
||||
* **LTO 링크 최적화 및 모듈 가지치기**: 경량 모드(Lite Mode)에서 `--lto=yes` 링크 타임 최적화 지원. PySide/PyQt 사용 시 참조되지 않은 무거운 하위 모듈(WebEngine, 3D, Quick 등)을 자동 식별 및 제거하여 바이너리 용량 낭비 방지.
|
||||
* **유연한 배포 형태**: **단일 파일 모드 (`--onefile`)** 및 **디렉터리 모드 (`--onedir`)** 지원, 내부 리소스 저장 디렉터리 경로 지정 (`--contents-directory`) 지원.
|
||||
|
||||
### 2. 정적 분석 및 의존성 토폴로지 보호
|
||||
* **순수 AST 재귀 스캔**: 순수 Python 기반의 추상 구문 트리(AST) 정적 분석기를 내장하여 코드를 실행하지 않고도 소스 코드와 프로젝트 폴더의 명시적/암시적 임포트를 재귀적으로 분석.
|
||||
* **스마트 패키지 이름 매핑 시스템**: 일반적인 서드파티 라이브러리 임포트 이름과 PyPI 패키지 이름 매핑 테이블 내장(예: `cv2` $\to$ `opencv-python`, `PIL` $\to$ `pillow`, `win32com` $\to$ `pywin32`), 사용자 정의 확장 지원.
|
||||
* **레거시 호환 패키지 동적 격리 (Backport Isolation)**: 대상 Python 버전의 표준 라이브러리와 충돌하는 구형 Backport 패키지(예: Python 3.10+ 환경의 `pathlib`, `typing` 등)를 자동 감지 및 차단.
|
||||
|
||||
### 3. 환경 자동화 관리 및 자체 복구 메커니즘
|
||||
* **C/C++ 컴파일러 자동 프로비저닝**: 로컬 MSVC, Clang (LLVM), GCC 환경 자동 감지. 네이티브 컴파일러가 없을 경우 Nuitka 엔진이 호환 가능한 MinGW-w64 툴체인을 자동 다운로드 및 관리.
|
||||
* **가상 환경 라이프사이클 관리**: 독립 격리 가상 환경 및 공유 가상 환경 모드 지원. 이전 프로젝트의 비활성 가상 환경 원클릭 스캔 및 정리 유틸리티 제공.
|
||||
* **리소스 인식형 동시성 및 오류 자가 치유**:
|
||||
* 빌드 전 디스크 용량과 물리 메모리를 평가하여 저메모리 상태에서 CPU 동시 작업 스레드 수(Adaptive Concurrency) 자동 조절.
|
||||
* 메모리 할당 오버플로(OOM / ZstdError)를 감지하고 단일 스레드 저메모리 모드로 자동 재시도.
|
||||
* Windows 백신 프로그램의 중간 아이콘/임시 파일 잠금 충돌 자동 우회.
|
||||
|
||||
### 4. 코드 서명 및 릴리스 보증
|
||||
* **스마트 디지털 서명 관리**: Windows 바이너리 빌드 완료 후 Authenticode 디지털 서명 자동 적용(Signtool 및 PowerShell 엔진 지원, RFC 3161 타임스탬프 서비스 통합). macOS의 원클릭 `codesign` 런타임 서명 지원.
|
||||
* **자체 서명 인증서 도구**: Windows 자체 서명 코드 서명 인증서(`.pfx`) 생성 도구 내장 및 상용 개인 키 인증서/비밀번호 구성 지원.
|
||||
* **프로젝트 설정 프리셋 가져오기/내보내기**: 모든 빌드 매개변수, 리소스 매핑 및 제외 규칙을 공유 가능한 `.qpypack` 프리셋 파일로 내보내어 팀 협업 및 CI/CD 워크플로 지원.
|
||||
|
||||
### 5. 크로스 플랫폼 사용자 경험
|
||||
* **드래그 앤 드롭 지원**: Python 스크립트를 드롭하면 모듈 메타데이터(버전, 작성자, 앱 이름) 파싱, 진입점 유추, 소스 디렉터리의 앱 아이콘 매핑 자동 수행.
|
||||
* **벡터 렌더링 및 글로벌 i18n**: Google Material SVG 벡터 아이콘을 적용하여 4K/고해상도 DPI 스케일링 완벽 지원. 한국어, 영어, 중국어(간체/번체), 일본어, 독일어, 프랑스어 등 17개 언어 실시간 다국어 지원.
|
||||
|
||||
---
|
||||
|
||||
## 📊 엔진 비교 (PyInstaller vs. Nuitka)
|
||||
|
||||
| 평가 지표 | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **패키징 방식** | Python 인터프리터 + 바이트코드 (`.pyc`) 번들링 | Python 코드를 네이티브 C/C++ 바이너리로 컴파일 |
|
||||
| **빌드 속도** | 매우 빠름 (보통 10 ~ 60초) | 상대적으로 느림 (C++ 코드 생성 및 최적화 수반) |
|
||||
| **C/C++ 컴파일러** | 불필요 | 필요 (MSVC / GCC / Clang / MinGW-w64 자동 관리) |
|
||||
| **코드 보호 수준** | 기본 (디컴파일러를 통한 소스 복원 가능) | 매우 높음 (기계어 바이너리, 강력한 역공학 방지) |
|
||||
| **실행 성능** | 표준 Python 실행 속도 | 빠른 시작 속도, 루프 및 연산 집약적 작업 최적화 |
|
||||
| **권장 사용 시나리오** | 빠른 프로토타입 검증, 내부 도구, 동적 임포트 프로젝트 | 상용 배포 소프트웨어, 핵심 알고리즘 보호, 용량/속도 최적화 |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ 빠른 시작 (Quick Start)
|
||||
|
||||
> 💡 **QPyPack을 처음 사용하시나요?** 자세한 사용 가이드와 모범 사례는 [**📖 빠른 시작 가이드 (QUICKSTART.md)**](../../QUICKSTART.md)를 참조하세요.
|
||||
|
||||
### 방법 1: pip / pipx를 통한 설치 (권장)
|
||||
|
||||
Python >= 3.8 환경에서 실행:
|
||||
|
||||
```bash
|
||||
# pip를 통한 설치
|
||||
pip install qpypack
|
||||
|
||||
# 실행
|
||||
# GUI 애플리케이션 실행
|
||||
qpypack
|
||||
```
|
||||
|
||||
또는 [GitHub Releases 페이지](https://github.com/Qwejay/QPyPack/releases)에서 사전 빌드된 실행 파일을 다운로드하세요.
|
||||
*최신 패키지 관리자 사용 시 (권장):*
|
||||
```bash
|
||||
# pipx를 통한 격리 실행
|
||||
pipx run qpypack
|
||||
|
||||
# uv를 통한 초고속 실행
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### 방법 2: 독립형 빌드 바이너리 버전
|
||||
|
||||
사전에 Python 환경을 구축할 필요 없이 GitHub Releases 페이지에서 해당 운영체제에 맞는 실행 파일을 직접 다운로드할 수 있습니다:
|
||||
|
||||
👉 [**사전 빌드 바이너리 다운로드 (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📅 변경 사항 (Changelog)
|
||||
## 📋 권장 설정: 리소스 해제 경로 (`sys._MEIPASS`)
|
||||
|
||||
자세한 릴리스 노트 및 업데이트 기록은 [CHANGELOG.md](CHANGELOG.md) 또는 [GitHub Releases 페이지](https://github.com/Qwejay/QPyPack/releases)를 참조하세요.
|
||||
단일 파일 모드(`--onefile`)에서는 포함된 정적 리소스(이미지, 설정 파일, 모델 등)가 실행 시 임시 샌드박스 디렉터리에 압축 해제됩니다. 소스 코드 내에서 다음과 같은 표준 방식으로 경로를 참조하십시오:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""패키징 후 리소스의 절대 경로를 안전하게 반환"""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# PyInstaller 단일 파일 압축 해제 임시 디렉터리
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Nuitka 네이티브 바이너리 실행 디렉터리
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# 로컬 개발 및 디버깅 디렉터리
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 변경 이력 (Changelog)
|
||||
|
||||
자세한 릴리스 정보, 신규 기능 및 버그 수정 내역은 [CHANGELOG.md](../../CHANGELOG.md)를 참조하세요.
|
||||
|
||||
---
|
||||
|
||||
## 💖 기여 및 후원 (Sponsorship & Contributing)
|
||||
|
||||
QPyPack은 오픈 소스 철학에 따라 유지 관리되는 프로젝트입니다. 본 프로젝트가 개발 효율 향상에 도움이 되었다면 지속적인 유지 관리를 위해 후원해 주실 수 있습니다:
|
||||
|
||||
- 🌟 **Star 지원**: [GitHub](https://github.com/Qwejay/QPyPack)에서 Star를 눌러주세요.
|
||||
- 🐛 **피드백 및 제안**: [GitHub Issues](https://github.com/Qwejay/QPyPack/issues)를 통해 버그를 보고하거나 개선 사항을 제안해 주세요.
|
||||
- ⚡ **프로젝트 후원**: [Afdian (爱发电)](https://www.ifdian.net/a/qwejay) 플랫폼을 통해 자발적 후원이 가능합니다 (WeChat Pay / Alipay 지원).
|
||||
|
||||
> *참고: 후원은 오픈 소스 프로젝트에 대한 자발적인 응원이며 상업적 서비스 약정을 포함하지 않습니다. 오픈 소스 생태계를 지원해 주시는 모든 분께 감사드립니다!*
|
||||
|
||||
---
|
||||
|
||||
## 📄 라이선스 (License)
|
||||
|
||||
[GNU General Public License v3.0](LICENSE)에 따라 오픈 소스로 제공됩니다.
|
||||
본 프로젝트는 [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE)에 따라 오픈 소스로 배포됩니다.
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
> [!IMPORTANT]
|
||||
> **빌드 결과물의 저작권 안내**:
|
||||
> QPyPack을 통해 빌드된 최종 애플리케이션 및 바이너리의 **지식재산권과 라이선스 형태는 전적으로 사용자에게 귀속됩니다**. QPyPack의 GPL-3.0 라이선스는 사용자가 패키징한 결과물에 전염되지 않습니다.
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+149
-25
@@ -14,70 +14,194 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Uma ferramenta GUI multiplataforma para empacotar aplicações Python baseada no PyInstaller & Nuitka</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
O QPyPack é uma ferramenta gráfica projetada para simplificar o empacotamento de aplicações Python. Ele integra perfeitamente os motores PyInstaller e Nuitka, convertendo argumentos complexos de linha de comando em uma interface intuitiva.
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>Ferramenta GUI moderna e pronta para uso para empacotar aplicações Python multiplataforma</strong><br>
|
||||
<sub>Alimentada pelos motores PyInstaller e Nuitka, com configuração visual, análise estática de dependências e fluxo de compilação automatizado.</sub>
|
||||
</p>
|
||||
|
||||
## 📌 Visão Geral do Projeto (Overview)
|
||||
|
||||
O **QPyPack** é uma ferramenta gráfica multiplataforma desenvolvida para simplificar o empacotamento de aplicações Python. Ao integrar perfeitamente os motores **PyInstaller** (agrupamento de bytecode) e **Nuitka** (compilação nativa C/C++), transforma cadeias de ferramentas complexas, análise de dependências implícitas, isolamento de ambientes e coleta de recursos em uma interface de usuário intuitiva.
|
||||
|
||||
Seja para distribuir scripts de automação simples ou aplicações complexas com dependências pesadas (como PySide6/PyQt, Playwright, CustomTkinter, FastAPI, etc.), o QPyPack oferece uma experiência de compilação estável, reproduzível e com alta taxa de sucesso no Windows, macOS e Linux.
|
||||
|
||||
---
|
||||
|
||||
## 📷 Capturas de Tela (Screenshots)
|
||||
## 📸 Capturas de Tela (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="Interface Principal (Inglês)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="Interface Principal (Chinês)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="Motor e Ambiente" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="Gerenciamento de Dependências" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="Otimização e Assinatura" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="Sobre e Diagnósticos" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Principais Recursos
|
||||
## 🛠️ Arquitetura e Principais Recursos
|
||||
|
||||
* 📥 **Arrastar e Soltar** : Arraste arquivos `.py` ou `.pyw` diretamente para a janela.
|
||||
* 🎨 **Detecção Automática de Ícone** : Converte e pré-visualiza ícones da pasta fonte.
|
||||
* 🛡️ **Ambiente Virtual Isolado** : Cria um ambiente virtual automaticamente para reduzir o tamanho do executável.
|
||||
* 🔍 **Análise de Dependências** : Leitura de `requirements.txt` e análise estática de código AST para importações ocultas.
|
||||
* ⚙️ **Troca de Motor Duplo** : Alterne facilmente entre PyInstaller e Nuitka.
|
||||
* 📝 **Injeção de Metadados** : Configure versão, autor e descrição diretamente na interface gráfica.
|
||||
### 1. Compilação por Motor Duplo e Otimização Binária
|
||||
* **Alternância fluida entre motores**:
|
||||
* **PyInstaller**: Compilação rápida, sem dependência de compiladores C externos, excelente compatibilidade.
|
||||
* **Nuitka**: Traduz código Python diretamente para binários C/C++ nativos para alto desempenho, forte proteção contra engenharia reversa e tamanho compacto.
|
||||
* **Otimização LTO e poda de submódulos**: Suporte a LTO (`--lto=yes`) no modo Lite. Identificação e exclusão automática de submódulos Qt pesados não utilizados (WebEngine, 3D, Quick, etc.) para evitar inchaço binário.
|
||||
* **Formatos de distribuição flexíveis**: Compatível com modo de **Arquivo único (`--onefile`)** e modo **Diretório (`--onedir`)**, com personalização do diretório interno de dependências (`--contents-directory`).
|
||||
|
||||
### 2. Análise Estática e Proteção de Dependências
|
||||
* **Varredura AST recursiva nativa**: Analisador estático de árvore de sintaxe abstrata (AST) em Python puro que descobre importações explícitas e implícitas sem executar o código.
|
||||
* **Mapeamento inteligente de pacotes**: Tabela de correspondência integrada entre nomes de importação e pacotes PyPI (ex: `cv2` $\to$ `opencv-python`, `PIL` $\to$ `pillow`, `win32com` $\to$ `pywin32`), modular e extensível.
|
||||
* **Isolamento dinâmico de bibliotecas obsoletas (Backport Isolation)**: Detecta e bloqueia pacotes de retrocompatibilidade obsoletos que entram em conflito com a biblioteca padrão moderna (ex: isolando `pathlib` ou `typing` no Python 3.10+).
|
||||
|
||||
### 3. Gerenciamento Automatizado de Ambiente e Autorrecuperação
|
||||
* **Provisionamento automático de compiladores C/C++**: Detecta MSVC, Clang (LLVM) e GCC locais. Caso nenhum compilador seja encontrado, o Nuitka baixa e gerencia automaticamente a toolchain MinGW-w64.
|
||||
* **Gerenciamento do ciclo de vida de ambientes virtuais**: Suporte para sandboxes isoladas e ambientes compartilhados com utilitário de limpeza integrado.
|
||||
* **Gerenciamento adaptativo de recursos e autorrecuperação**:
|
||||
* Avalia RAM e espaço em disco antes da compilação, ajustando a concorrência de threads (Adaptive Concurrency).
|
||||
* Captura falhas de memória saturada (`ZstdError` / OOM) e reinicia a compilação no modo mono-thread de baixo consumo.
|
||||
* Evita bloqueios exclusivos de arquivos causados por antivírus ou serviços de sincronização em nuvem.
|
||||
|
||||
### 4. Assinatura de Código e Predefinições de Projeto
|
||||
* **Assinatura digital inteligente**: Aplica assinaturas digitais Authenticode em binários Windows (compatível com Signtool e PowerShell com carimbo de data/hora RFC 3161) e assinatura runtime `codesign` no macOS.
|
||||
* **Suite de certificados**: Gerador integrado de certificados autoassinados (`.pfx`) e suporte para certificados comerciais.
|
||||
* **Importação/Exportação de predefinições**: Salva todos os parâmetros de compilação, listas de recursos e regras em arquivos `.qpypack`.
|
||||
|
||||
### 5. Experiência de Usuário e Internacionalização (i18n)
|
||||
* **Arrastar e soltar intuitivo**: Ao soltar um script Python, extrai metadados (`__version__`, `__author__`), deduz o ponto de entrada e mapeia o ícone da aplicação.
|
||||
* **Interface vetorial com suporte HiDPI**: Construída com ícones vetoriais Google Material SVG, com dimensionamento perfeito em monitores 4K. Traduzida para 17 idiomas (português, inglês, chinês, japonês, coreano, alemão, francês, espanhol, etc.).
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Início Rápido
|
||||
## 📊 Comparativo de Motores (PyInstaller vs. Nuitka)
|
||||
|
||||
| Critério | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **Princípio** | Empacota interpretador Python + bytecode (`.pyc`) | Compila código Python para binários C/C++ nativos |
|
||||
| **Velocidade de compilação** | Muito rápida (geralmente 10 – 60 s) | Mais lenta (requer geração de código C++ e otimizações) |
|
||||
| **Compilador C/C++** | Não necessário | Necessário (gestão automática de MSVC / GCC / Clang / MinGW-w64) |
|
||||
| **Nível de proteção** | Básico (código recuperável via descompiladores) | Extremamente alto (código de máquina nativo, alta proteção) |
|
||||
| **Desempenho de execução**| Velocidade padrão do Python | Inicialização mais rápida, laços e computação otimizados |
|
||||
| **Recomendado para** | Prototipagem rápida, ferramentas internas, projetos dinâmicos | Software comercial, proteção de algoritmos, otimização de tamanho |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Início Rápido (Quick Start)
|
||||
|
||||
> 💡 **Primeira vez usando o QPyPack?** Consulte nosso [**📖 Guia de Início Rápido (QUICKSTART.md)**](../../QUICKSTART.md) para um tutorial passo a passo e configurações recomendadas.
|
||||
|
||||
### Método 1: Instalação via pip / pipx (Recomendado)
|
||||
|
||||
Requer Python >= 3.8:
|
||||
|
||||
```bash
|
||||
# Instalar via pip
|
||||
pip install qpypack
|
||||
|
||||
# Iniciar aplicação
|
||||
# Iniciar a aplicação gráfica
|
||||
qpypack
|
||||
```
|
||||
|
||||
Ou baixe executáveis pré-compilados diretamente na página de [Releases do GitHub](https://github.com/Qwejay/QPyPack/releases).
|
||||
*Com gerenciadores de pacotes modernos:*
|
||||
```bash
|
||||
# Executar isolado via pipx
|
||||
pipx run qpypack
|
||||
|
||||
# Inicialização ultrarrápida via uv
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### Método 2: Versão binária pré-compilada independente
|
||||
|
||||
Sem necessidade de configurar o Python localmente, baixe os executáveis pré-compilados diretamente na página de lançamentos:
|
||||
|
||||
👉 [**Baixar versões pré-compiladas (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Resolução de Caminhos de Recursos (`sys._MEIPASS`)
|
||||
|
||||
No modo de arquivo único (`--onefile`), os recursos estáticos (imagens, arquivos de configuração, modelos) são extraídos temporariamente durante a execução. Utilize o seguinte padrão padrão para resolver caminhos:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""Obtém o caminho absoluto para recursos empacotados."""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# Diretório de extração temporária do PyInstaller
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Diretório de execução do binário Nuitka
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# Ambiente de desenvolvimento local
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 Registro de Alterações (Changelog)
|
||||
|
||||
Para ver o histórico completo de atualizações, consulte [CHANGELOG.md](CHANGELOG.md) ou a página de [Releases do GitHub](https://github.com/Qwejay/QPyPack/releases).
|
||||
Para notas de versão detalhadas e correções de bugs, consulte o arquivo [CHANGELOG.md](../../CHANGELOG.md).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Licença
|
||||
## 💖 Contribuição e Patrocínio
|
||||
|
||||
Distribuído sob a licença [GNU General Public License v3.0](LICENSE).
|
||||
O QPyPack é um projeto de código aberto mantido no meu tempo livre. Se esta ferramenta foi útil para você, agradecemos seu apoio voluntário:
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
- 🌟 **Estrela no GitHub**: Deixe uma estrela no repositório no [GitHub](https://github.com/Qwejay/QPyPack).
|
||||
- 🐛 **Feedback e Sugestões**: Envie relatórios de bugs e melhorias no [GitHub Issues](https://github.com/Qwejay/QPyPack/issues).
|
||||
- ⚡ **Patrocínio**: Apoie o autor através do [Afdian (爱发电)](https://www.ifdian.net/a/qwejay) (compatível com WeChat Pay / Alipay).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Licença (License)
|
||||
|
||||
Este projeto está licenciado sob a [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Direitos autorais sobre binários gerados**:
|
||||
> Os direitos de propriedade intelectual e termos de licença das aplicações criadas com o QPyPack **pertencem integralmente ao usuário**. A licença GPL-3.0 do QPyPack não impõe restrições ao seu software compilado.
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+149
-25
@@ -14,70 +14,194 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>Кроссплатформенный GUI-инструмент упаковки Python-приложений на базе PyInstaller и Nuitka</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue" alt="PyPI version" />
|
||||
<img src="https://img.shields.io/pypi/v/qpypack.svg?color=blue&logo=pypi&logoColor=white" alt="PyPI version" />
|
||||
</a>
|
||||
<!-- Python Versions -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg" alt="Python versions" />
|
||||
<img src="https://img.shields.io/pypi/pyversions/qpypack.svg?logo=python&logoColor=white" alt="Python versions" />
|
||||
</a>
|
||||
<!-- PyPI Downloads -->
|
||||
<a href="https://pypistats.org/packages/qpypack">
|
||||
<img src="https://img.shields.io/pypi/dm/qpypack?color=orange&logo=pypi&logoColor=white" alt="PyPI Downloads" />
|
||||
</a>
|
||||
<!-- Supported Platforms -->
|
||||
<img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-informational" alt="Platform Support" />
|
||||
<br>
|
||||
<!-- Release Date -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/releases">
|
||||
<img src="https://img.shields.io/github/release-date/Qwejay/QPyPack?color=brightgreen&logo=github" alt="Release Date" />
|
||||
</a>
|
||||
<!-- Last Commit -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/commits/main">
|
||||
<img src="https://img.shields.io/github/last-commit/Qwejay/QPyPack" alt="Last Commit" />
|
||||
</a>
|
||||
<!-- GitHub License -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Qwejay/QPyPack.svg" alt="License" />
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg" alt="GitHub stars" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub stars" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack — это визуальный инструмент, предназначенный для упрощения процесса сборки приложений Python. Он объединяет два основных компилятора — PyInstaller и Nuitka, преобразуя сложные консольные команды в интуитивный графический интерфейс.
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>Современный кроссплатформенный GUI-инструмент для упаковки Python-приложений</strong><br>
|
||||
<sub>На базе PyInstaller и Nuitka, с визуальной конфигурацией, статическим анализом зависимостей и автоматизацией сборки.</sub>
|
||||
</p>
|
||||
|
||||
## 📌 Обзор проекта (Overview)
|
||||
|
||||
**QPyPack** — это графический кроссплатформенный инструмент для упаковки Python-приложений. Благодаря глубокой интеграции двух компиляторов — **PyInstaller** (бандлинг байт-кода) и **Nuitka** (нативная компиляция в C/C++) — сложные параметры командной строки, отслеживание неявных зависимостей, изоляция сред и сбор ресурсов объединены в удобном интерфейсе.
|
||||
|
||||
От простых скриптов автоматизации до сложных приложений (с PySide6/PyQt, Playwright, CustomTkinter, FastAPI и др.) — QPyPack гарантирует стабильную сборку с высоким процентом успеха на Windows, macOS и Linux.
|
||||
|
||||
---
|
||||
|
||||
## 📷 Скриншоты (Screenshots)
|
||||
## 📸 Скриншоты (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1143" height="1067" alt="image" src="https://github.com/user-attachments/assets/8658aaef-5867-470d-ba4d-07892309ab1a" />
|
||||
<img width="1142" height="1067" alt="image" src="https://github.com/user-attachments/assets/b64d9b89-8bfd-4bf8-8fec-9c75f61305dd" />
|
||||
<img width="32%" alt="Главное окно (Английский)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="Главное окно (Китайский)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="Движок и окружение" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="Управление зависимостями" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="Оптимизация и подпись" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="О программе и диагностика" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Основные возможности
|
||||
## 🛠️ Архитектура и ключевые возможности
|
||||
|
||||
* 📥 **Drag & Drop** : Перетаскивайте файлы `.py` или `.pyw` прямо в окно программы.
|
||||
* 🎨 **Автоопределение иконки** : Автоматически находит иконки в папке исходников и конвертирует их.
|
||||
* 🛡️ **Виртуальное окружение (Sandbox)** : Создает изолированное окружение для минимизации размера итогового файла.
|
||||
* 🔍 **Анализ зависимостей** : Считывание `requirements.txt` и статический AST-анализ кода для скрытых импортов.
|
||||
* ⚙️ **Два движка сборки** : Быстрое переключение между PyInstaller и Nuitka.
|
||||
* 📝 **Внедрение метаданных** : Указывайте версию, автора и описание приложения прямо в интерфейсе.
|
||||
### 1. Двойной движок сборки и оптимизация бинарных файлов
|
||||
* **Плавное переключение движков**:
|
||||
* **PyInstaller**: Высокая скорость сборки, отсутствие потребности в C-компиляторе, отличная совместимость.
|
||||
* **Nuitka**: Транслирует Python-код напрямую в C/C++ бинарники, обеспечивая высокую скорость выполнения, стойкость к декомпиляции и компактный размер.
|
||||
* **LTO-оптимизация и обрезка модулей**: Поддержка оптимизации на этапе компоновки (`--lto=yes`) в режиме Lite. Автоматическое исключение неиспользуемых тяжелых субмодулей Qt (WebEngine, 3D, Quick и др.).
|
||||
* **Гибкие форматы сборки**: Поддержка режимов **одного файла (`--onefile`)** и **директории (`--onedir`)**, а также настройка внутреннего каталога зависимостей (`--contents-directory`).
|
||||
|
||||
### 2. Статический анализ и защита зависимостей
|
||||
* **Рекурсивный AST-анализ**: Встроенный анализатор абстрактного синтаксического дерева (AST) на чистом Python, определяющий явные и неявные импорты без запуска кода.
|
||||
* **Интеллектуальное сопоставление пакетов**: Встроенная таблица соответствия имён импорта и пакетов PyPI (например, `cv2` $\to$ `opencv-python`, `PIL` $\to$ `pillow`, `win32com` $\to$ `pywin32`) с возможностью расширения.
|
||||
* **Динамическая изоляция устаревших бэкпортов**: Автоматически блокирует устаревшие backport-модули, конфликтующие со стандартной библиотекой (например, изоляция `pathlib` или `typing` в Python 3.10+).
|
||||
|
||||
### 3. Автоматизация окружения и отказоустойчивость
|
||||
* **Автоматическое управление компиляторами C/C++**: Определяет установленные MSVC, Clang (LLVM) и GCC. При отсутствии компилятора Nuitka автоматически загружает MinGW-w64.
|
||||
* **Управление виртуальными окружениями**: Поддержка изолированных и общих виртуальных сред, а также встроенная утилита очистки старых сред.
|
||||
* **Адаптивный контроль ресурсов и самовосстановление**:
|
||||
* Оценивает ОЗУ и диск перед сборкой, автоматически снижая параллелизм потоков при нехватке памяти.
|
||||
* Перехватывает ошибки нехватки памяти (`ZstdError` / OOM) и автоматически перезапускает сборку в однопоточном режиме.
|
||||
* Обходит временные блокировки файлов антивирусами и облачными дисками.
|
||||
|
||||
### 4. Подпись кода и пресеты проектов
|
||||
* **Умная цифровая подпись**: Автоматически подписывает исполняемые файлы Windows через Authenticode (Signtool/PowerShell с меткой времени RFC 3161) и выполняет `codesign` в macOS.
|
||||
* **Генератор сертификатов**: Встроенный инструмент создания самоподписанных сертификатов (`.pfx`) и поддержка коммерческих ключей.
|
||||
* **Импорт/экспорт пресетов**: Сохраняет все параметры сборки и списки ресурсов в файлы `.qpypack`.
|
||||
|
||||
### 5. Кроссплатформенный интерфейс и локализация
|
||||
* **Удобный Drag & Drop**: При перетаскивании скрипта автоматически извлекаются метаданные (`__version__`, `__author__`), определяется точка входа и подбирается иконка.
|
||||
* **Векторная графика и поддержка HiDPI**: Построен на векторных иконках Google Material SVG, отлично масштабируется на экранах 4K. Переведён на 17 языков (русский, английский, китайский, японский, корейский, немецкий, французский, испанский и др.).
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Быстрый старт
|
||||
## 📊 Сравнение движков (PyInstaller vs. Nuitka)
|
||||
|
||||
| Критерий | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **Принцип работы** | Упаковывает интерпретатор Python + байт-код (`.pyc`) | Компилирует Python в нативные C/C++ бинарники |
|
||||
| **Скорость сборки** | Очень высокая (10 – 60 сек) | Более медленная (генерация C++ и компиляция) |
|
||||
| **Компилятор C/C++** | Не требуется | Требуется (MSVC / GCC / Clang / MinGW-w64) |
|
||||
| **Защита кода** | Базовая (исходники можно извлечь декомпилятором) | Максимальная (машинный код, защита от реверс-инжиниринга) |
|
||||
| **Производительность** | Стандартная скорость Python | Быстрый запуск, ускорение циклов и вычислений |
|
||||
| **Рекомендуется для** | Быстрого тестирования, внутренних утилит, динамических скриптов | Коммерческого ПО, защиты интеллектуальной собственности, оптимизации |
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Быстрый старт (Quick Start)
|
||||
|
||||
> 💡 **Впервые используете QPyPack?** Ознакомьтесь с [**📖 Руководством по быстрому старту (QUICKSTART.md)**](../../QUICKSTART.md).
|
||||
|
||||
### Способ 1: Установка через pip / pipx (Рекомендуется)
|
||||
|
||||
Требуется Python >= 3.8:
|
||||
|
||||
```bash
|
||||
# Установка через pip
|
||||
pip install qpypack
|
||||
|
||||
# Запуск
|
||||
# Запуск приложения
|
||||
qpypack
|
||||
```
|
||||
|
||||
Или скачайте готовые исполняемые файлы на странице [GitHub Releases](https://github.com/Qwejay/QPyPack/releases).
|
||||
*С современными пакетными менеджерами:*
|
||||
```bash
|
||||
# Изолированный запуск через pipx
|
||||
pipx run qpypack
|
||||
|
||||
# Быстрый запуск через uv
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### Способ 2: Готовые скомпилированные версии
|
||||
|
||||
Без предварительной настройки Python скачайте готовые исполняемые файлы со страницы релизов:
|
||||
|
||||
👉 [**Скачать релизы (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Разрешение путей к ресурсам (`sys._MEIPASS`)
|
||||
|
||||
В режиме одного файла (`--onefile`) статические ресурсы (изображения, конфигурации, модели) распаковываются во временный каталог. Используйте следующий шаблон:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""Получение абсолютного пути к упакованным ресурсам."""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# Временная папка распаковки PyInstaller
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Директория запуска бинарника Nuitka
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# Локальное окружение разработки
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📅 История изменений (Changelog)
|
||||
|
||||
Полную историю версий и примечания к релизу см. в [CHANGELOG.md](CHANGELOG.md) или на странице [GitHub Releases](https://github.com/Qwejay/QPyPack/releases).
|
||||
Подробный список изменений версий доступен в [CHANGELOG.md](../../CHANGELOG.md).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Лицензия
|
||||
## 💖 Участие и поддержка проекта
|
||||
|
||||
Распространяется под лицензией [GNU General Public License v3.0](LICENSE).
|
||||
QPyPack — это проект с открытым исходным кодом. Если инструмент помог вам в разработке, вы можете поддержать автора:
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
- 🌟 **Поставьте Star**: Отметьте репозиторий звездой на [GitHub](https://github.com/Qwejay/QPyPack).
|
||||
- 🐛 **Обратная связь**: Создавайте тикеты на [GitHub Issues](https://github.com/Qwejay/QPyPack/issues).
|
||||
- ⚡ **Спонсорство**: Поддержите автора через [Afdian (爱发电)](https://www.ifdian.net/a/qwejay) (WeChat Pay / Alipay).
|
||||
|
||||
---
|
||||
|
||||
## 📄 Лицензия (License)
|
||||
|
||||
Проект распространяется под лицензией [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Авторские права на собранные приложения**:
|
||||
> Права интеллектуальной собственности и лицензия на созданные вами приложения **полностью принадлежат вам**. Лицензия GPL-3.0 проекта QPyPack не накладывает ограничений на созданные вами программы.
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+121
-59
@@ -13,10 +13,6 @@
|
||||
<a href="README_PT.md">Português</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<strong>基於 PyInstaller 與 Nuitka 的跨平台 Python 應用程式視覺化打包建置工具</strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<!-- PyPI Version -->
|
||||
<a href="https://pypi.org/project/qpypack/">
|
||||
@@ -47,102 +43,168 @@
|
||||
</a>
|
||||
<!-- GitHub Stars -->
|
||||
<a href="https://github.com/Qwejay/QPyPack/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github" alt="GitHub 星星數" />
|
||||
<img src="https://img.shields.io/github/stars/Qwejay/QPyPack.svg?logo=github&color=gold" alt="GitHub 星星數" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
QPyPack 是一款致力於簡化 Python 應用程式打包流程的視覺化工具。它深度整合了 **PyInstaller** 與 **Nuitka** 兩大主流編譯引擎,將繁瑣的終端機命令列參數轉化為直觀、極簡的圖形介面互動,協助開發者高效、高成功率地產生跨平台原生可執行程式。
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>現代化、開箱即用的跨平台 Python 應用程式打包 GUI 工具</strong><br>
|
||||
<sub>基於 PyInstaller 與 Nuitka 雙引擎驅動,提供視覺化配置、靜態相依性分析與自動化建置工作流程</sub>
|
||||
</p>
|
||||
|
||||
## 📌 專案概述
|
||||
|
||||
**QPyPack** 是一款專為 Python 開發者打造的跨平台圖形化打包工具。透過深度整合 **PyInstaller**(直譯器與位元組碼打包)與 **Nuitka**(C/C++ 原生編譯)雙核心引擎,將繁瑣的底層編譯參數、隱式相依性分析、環境隔離與資源收集等流程轉化為直觀的可視化介面。
|
||||
|
||||
無論是用於打包輕量命令列指令碼,還是包含大型複雜相依性(如 PySide6 / PyQt、Playwright、CustomTkinter、FastAPI 等)的桌面或伺服端應用,QPyPack 均可提供穩定、高成功率且可重現的建置體驗。
|
||||
|
||||
---
|
||||
|
||||
## 📷 介面預覽 (Screenshots)
|
||||
## 📸 介面預覽 (Screenshots)
|
||||
|
||||
<p align="center">
|
||||
<img width="1173" height="1067" alt="主介面預覽" src="https://github.com/user-attachments/assets/6cf1e937-d35f-4e71-b4e7-7fd86f771d20" />
|
||||
<img width="1173" height="1067" alt="設定面板預覽" src="https://github.com/user-attachments/assets/b4f563fb-328b-4615-8522-e4f9e490f759" />
|
||||
<img width="1173" height="1067" alt="相依性管理預覽" src="https://github.com/user-attachments/assets/522d7a3b-9a01-4387-8e81-def4cabcbfff" />
|
||||
<img width="1173" height="1067" alt="進階優化預覽" src="https://github.com/user-attachments/assets/c8a89212-bf48-40d0-8125-98595f6052bd" />
|
||||
<img width="1173" height="1067" alt="關於頁面預覽" src="https://github.com/user-attachments/assets/3f5b803a-3c96-493c-b56b-e11f50bd9139" />
|
||||
<img width="32%" alt="主介面(英文)" src="https://github.com/user-attachments/assets/9d16c68e-d283-4020-86c1-9d4791756c29" />
|
||||
<img width="32%" alt="主介面(中文)" src="https://github.com/user-attachments/assets/0147460d-1e9e-4612-9b52-9d347d81b7c5" />
|
||||
<img width="32%" alt="建置引擎與環境" src="https://github.com/user-attachments/assets/0ad4db6d-b008-4018-bd69-40a369a10b7d" />
|
||||
<br />
|
||||
<img width="32%" alt="相依性管理與掃描" src="https://github.com/user-attachments/assets/c7fd1218-d079-4898-a97c-aa980c4d1375" />
|
||||
<img width="32%" alt="最佳化、簽名與安全" src="https://github.com/user-attachments/assets/e5b7500e-2a0d-4c6d-b20b-7d8d2d3bac8d" />
|
||||
<img width="32%" alt="關於與系統資訊" src="https://github.com/user-attachments/assets/e652b222-49f5-44cd-ad3f-d93369ede26b" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 🚀 核心特性 (Key Features)
|
||||
## 🛠️ 核心架構與特性
|
||||
|
||||
QPyPack 旨在解決傳統命令列打包設定繁瑣、相依性遺漏、跨平台相容性差以及編譯失敗率高的問題:
|
||||
### 1. 雙建置引擎與精簡最佳化
|
||||
* **雙引擎無縫切換**:
|
||||
* **PyInstaller**:建置速度快,零 C 編譯器相依,兼具優異的相容性與生態支援。
|
||||
* **Nuitka**:將 Python 原始碼直接轉譯為 C/C++ 二進位檔,具備執行速度快、抗反編譯能力強、產物體積小等特點。
|
||||
* **LTO 連結最佳化與模組修剪**:在精簡模式(Lite Mode)下支援開啟 `--lto=yes` 連結時間最佳化;針對 PySide/PyQt 自動識別並剔除未引用的重型子模組(如 WebEngine、3D、Quick 等),有效防止產物體積冗餘。
|
||||
* **靈活產物形態**:支援 **單檔案 (`--onefile`)** 與 **目錄模式 (`--onedir`)**,支援自訂相依性內部存放目錄 (`--contents-directory`)。
|
||||
|
||||
### 1. 現代化 UI 與直觀互動體驗
|
||||
* 📥 **拖放式載入 (Drag & Drop)**:只需將 `.py` 或 `.pyw` 原始程式碼檔案拖入視窗,系統全自動完成剖析與工作區初始化。
|
||||
* 🎨 **純向量圖示棧 (Material Design SVG)**:全介面採用 Google Material 向量圖示,全面清理 Emoji 表情,徹底杜絕跨平台系統下字型遞補導致的排版亂碼與跳動。
|
||||
* 🌐 **智慧多語言 (i18n)**:原生支援簡體中文、繁體中文、英文、德語、法語、日語、韓語等全球主流語言,自動辨識系統偏好語言並支援無縫切換。
|
||||
* 📊 **雙模式即時日誌檢視器**:引入「精簡模式 (Concise)」與「詳細模式 (Detailed)」雙檢視日誌面板,支援即時擷取編譯引擎極細粒度的編譯進度、一鍵匯出與高亮提示。
|
||||
### 2. 靜態分析與相依性拓撲防護
|
||||
* **原生 AST 遞迴掃描**:內建純 Python 實現的抽象語法樹(AST)靜態分析器,無需執行程式碼即可遞迴分析原始碼及專案目錄中的相依性匯入。
|
||||
* **智慧套件名稱對應系統**:內建主流第三方函式庫匯入名稱與 PyPI 套件名稱對應表(如 `cv2` $\to$ `opencv-python`、`PIL` $\to$ `pillow`、`win32com` $\to$ `pywin32`),支援使用者自訂擴充。
|
||||
* **廢棄相容套件動態隔離 (Backport Isolation)**:自動識別並屏蔽與目標 Python 版本內建模組衝突的過時 Backport 函式庫(如在 Python 3.10+ 下自動隔離 `pathlib`、`typing` 等),防止執行期引發不可預測的命名空間覆蓋。
|
||||
|
||||
### 2. 雙編譯後端與智慧環境偵測
|
||||
* ⚙️ **PyInstaller & Nuitka 架構**:圖形化介面一鍵切換引擎,根據所選引擎自適應提供針對性的優化選項與參數控制。
|
||||
* 🔍 **C/C++ 編譯器智慧偵測**:Nuitka 引擎下自動偵測系統內已安裝的 **MSVC**、**Clang** (LLVM) 及 **Zig**(專為 Python 3.13+ C 後端優化)編譯器並優先呼叫,免除繁瑣的環境變數設定。
|
||||
* 💻 **Python 平台相容性卡片**:動態顯示當前選中 Python 解譯器對 Windows 7/8/10/11、macOS 及 Linux 的支援狀態,並提供官方下載引導。
|
||||
### 3. 環境自動化管理與容錯機制
|
||||
* **C/C++ 編譯器自動託管**:自動偵測本機 MSVC、Clang (LLVM) 與 GCC 環境;在缺失本機編譯器時,Nuitka 引擎將自動下載並託管相容的 MinGW-w64 工具鏈。
|
||||
* **環境生命週期管理**:支援獨立隔離虛擬環境與共享虛擬環境模式;支援對歷史失效虛擬環境的一鍵掃描與空間清理。
|
||||
* **自適應資源與錯誤自癒**:
|
||||
* 建置前自動評估磁碟與實體記憶體,低記憶體狀態下自適應下調並行數(Adaptive Concurrency)。
|
||||
* 自動攔截記憶體配置溢位(OOM / ZstdError)並自動降級為單執行緒低記憶體模式重試。
|
||||
* 自動規避 Windows 防毒軟體對中繼圖示/暫存檔案的獨占鎖定。
|
||||
|
||||
### 3. 三重安全相依性網與零設定預設
|
||||
* 🛡️ **隔離虛擬沙盒 (Virtualenv Sandbox)**:一鍵在系統暫存目錄建立純淨建置沙盒,避免全域環境污染,極大精簡產物體積。
|
||||
* 🔍 **多維相依性自動補全**:優先讀取 `requirements.txt`;搭配深度原生 **AST(靜態語法樹)** 掃描引擎與 `pipreqs`,精準補齊隱式匯入(Hidden Imports)。
|
||||
* 📦 **免設定第三方套件打包預設**:內建對 `ttkbootstrap`、`customtkinter`、`playwright`、`moviepy` 等高頻缺失/報錯套件的自動化打包處理,實現零設定一鍵產生。
|
||||
* ⚡ **多源 PIP 鏡像與備用切源**:內建主流鏡像加速源,支援主源逾時自動平滑切換至備用源。
|
||||
### 4. 程式碼簽名與交付保障
|
||||
* **智慧數位簽名託管**:支援在 Windows 產物輸出後自動套用 Authenticode 數位簽名(相容 Signtool 與 PowerShell 引擎,整合 RFC 3161 時間戳記服務);支援 macOS 下的一鍵 `codesign` 程式碼簽名。
|
||||
* **自簽名憑證套件**:內建 Windows 自簽名程式碼簽名憑證(`.pfx`)產生工具,支援商業私密金鑰憑證與密碼配置。
|
||||
* **專案配置預設匯入/匯出**:支援將所有建置參數、資源清單與對應規則匯出為獨立的 `.qpypack` 專案工程預設檔案,便於團隊共享與持續整合。
|
||||
|
||||
### 4. 強健的建置容錯與自癒降級
|
||||
* 📏 **編譯前實體資源評估**:自動評估實體記憶體與磁碟可用空間,智慧調整併發 CPU 核心數。
|
||||
* 🛡️ **OOM 記憶體溢出自癒**:建置過程中遭遇 `ZstdError`(記憶體溢出)時,自動觸發單執行緒 (`--jobs=1`) 降級重試。
|
||||
* 🛡️ **圖示鎖定抗性**:遭遇防毒軟體或系統鎖定圖示檔案時,自動觸發剝離圖示參數自癒建置,保障二進位產物順利產生。
|
||||
* ☁️ **雲端硬碟鎖定預警**:前置感知識別 OneDrive / Dropbox 等雲端硬碟對檔案的鎖定同步狀態並提供明確排查提示。
|
||||
|
||||
### 5. 資源管理與應用程式元資料
|
||||
* 📝 **PE / Plist 元資料注入**:直接在介面設定版本號、公司名稱、產品描述,全自動寫入 Windows PE VersionInfo 或 macOS `Info.plist` 結構。
|
||||
* 📂 **視覺化附加資源管理**:提供列表化介面管理附加檔案與資料夾,支援雙擊直接編輯打包後的相對釋放路徑(自適應路徑對映)。
|
||||
### 5. 跨平台互動體驗
|
||||
* **拖放即用**:直接拖入 Python 原始碼即可自動解析模組元資料(版本、作者、應用程式名稱)、推導進入點並匹配同層資源圖示。
|
||||
* **向量渲染與全球化 i18n**:全介面基於 Google Material SVG 向量圖示繪製,完美適配 4K/高解析度螢幕 DPI 縮放;內建涵蓋簡繁中文、英語、日語、韓語、德語、法語等 17 種語言的即時國際化系統。
|
||||
|
||||
---
|
||||
|
||||
## ⚡ 快速上手 (Quick Start)
|
||||
## 📊 引擎選型對比 (PyInstaller vs. Nuitka)
|
||||
|
||||
### 方法一:透過 pip 安裝並執行
|
||||
| 評估維度 | PyInstaller | Nuitka |
|
||||
| :--- | :--- | :--- |
|
||||
| **打包原理** | 打包 Python 直譯器與位元組碼檔案 (`.pyc`) | 將 Python 程式碼編譯為原生 C/C++ 二進位檔案 |
|
||||
| **建置速度** | 極快(通常 10 ~ 60 秒) | 較慢(涉及 C++ 程式碼產生與編譯器最佳化) |
|
||||
| **C/C++ 編譯器相依** | 無需任何外部編譯器 | 相依 MSVC / GCC / Clang(支援自動託管下載) |
|
||||
| **程式碼保護等級** | 基礎(可透過反編譯工具還原原始碼邏輯) | 極高(原生機器碼,深層抗逆向分析) |
|
||||
| **產物執行效能** | 接近原生 Python 執行速度 | 啟動速度快,部分迴圈與計算密集型邏輯更優 |
|
||||
| **推薦適用場景** | 快速反覆運算測試、內部工具、複雜動態匯入專案 | 商業交付軟體、核心演算法保護、追求體積與啟動速度 |
|
||||
|
||||
在 Python >= 3.8 的環境中,執行以下命令進行安裝與啟動:
|
||||
---
|
||||
|
||||
## ⚡ 快速開始 (Quick Start)
|
||||
|
||||
> 💡 **首次使用?** 建議查閱 3 分鐘 [**📖 快速入門指南 (QUICKSTART.md)**](../../QUICKSTART.md) 了解詳細的使用教學與典型情境配置指南。
|
||||
|
||||
### 安裝方式 1:透過 pip / pipx 安裝(推薦)
|
||||
|
||||
在 Python >= 3.8 的環境中執行:
|
||||
|
||||
```bash
|
||||
# 安裝 QPyPack
|
||||
# 透過 pip 安裝
|
||||
pip install qpypack
|
||||
|
||||
# 啟動程式
|
||||
# 啟動圖形介面
|
||||
qpypack
|
||||
```
|
||||
|
||||
### 方法二:下載獨立二進位免安裝版
|
||||
*若使用現代套件管理器(推薦):*
|
||||
```bash
|
||||
# 使用 pipx 隔離執行
|
||||
pipx run qpypack
|
||||
|
||||
如果您不想設定本地 Python 環境,可直接在 GitHub Release 頁面下載對應系統的預編譯打包版本:
|
||||
👉 [下載預編譯版本 (GitHub Releases)](https://github.com/Qwejay/QPyPack/releases)
|
||||
# 或使用 uv 極速啟動
|
||||
uvx qpypack
|
||||
```
|
||||
|
||||
### 安裝方式 2:使用獨立預編譯免安裝版
|
||||
|
||||
無需預先安裝 Python 環境,可直接在 GitHub Release 頁面下載適用於您作業系統的可執行檔:
|
||||
|
||||
👉 [**下載預編譯版本 (GitHub Releases)**](https://github.com/Qwejay/QPyPack/releases)
|
||||
|
||||
---
|
||||
|
||||
## 📅 更新日誌 (Changelog)
|
||||
## 📋 常用配置說明
|
||||
|
||||
完整的版本更新歷史與 Release 說明請參閱 [CHANGELOG.md](../../CHANGELOG.md) 或 [GitHub Releases 頁面](https://github.com/Qwejay/QPyPack/releases)。
|
||||
### 相依性與資源釋放路徑 (`sys._MEIPASS`)
|
||||
在單檔案打包模式下,附加的資料檔案(圖片、配置、模型等)會在執行期暫時解壓縮至特定沙盒目錄。請確保在原始碼中按如下標準方式解析路徑:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def get_asset_path(relative_path: str) -> Path:
|
||||
"""取得打包後資源的絕對路徑"""
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
# PyInstaller 單檔案解壓縮目錄
|
||||
base_path = Path(sys._MEIPASS)
|
||||
elif "__compiled__" in globals():
|
||||
# Nuitka 二進位執行目錄
|
||||
base_path = Path(sys.argv[0]).resolve().parent
|
||||
else:
|
||||
# 開發偵錯環境目錄
|
||||
base_path = Path(__file__).resolve().parent
|
||||
return base_path / relative_path
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💖 贊助支援 (Sponsorship)
|
||||
## 📅 版本更新歷史 (Changelog)
|
||||
|
||||
QPyPack 是一款完全開源且免費的專案,由作者利用業餘時間開發與維護。如果本專案協助您提高了開發效率或解決了打包難題,歡迎透過以下方式對專案進行**自願贊助**。您的支援將是本專案持續更新的重要動力:
|
||||
|
||||
- ⚡ **請作者喝咖啡**:[贊助支援 QPyPack](https://www.ifdian.net/a/qwejay)(支援微信 / 支付寶)
|
||||
|
||||
> **贊助說明**:贊助完全出於自願,屬於對開源專案的無償鼓勵,不包含任何商業服務繫結或特定功能開發承諾。非常感謝每一位支援開源創作的朋友!
|
||||
詳細的版本演進路線、功能新增與缺陷修復說明請參閱 [CHANGELOG.md](../../CHANGELOG.md)。
|
||||
|
||||
---
|
||||
|
||||
## 📄 開源條款 (License)
|
||||
## 💖 參與貢獻與贊助 (Sponsorship & Contributing)
|
||||
|
||||
本專案基於 [GNU General Public License v3.0](LICENSE) 開源,允許在遵循條款的前提下自由分發、修改和二次開發。
|
||||
QPyPack 是一個遵循開源理念的專案。如果您在日常開發或工作中受益於本專案,歡迎透過以下方式支援本專案的長期維護與反覆運算:
|
||||
|
||||
> [!NOTE]
|
||||
> **關於打包產物的版權**:
|
||||
> 使用 QPyPack 建置產生的二進位檔案/應用程式,其版權和開源許可**完全由使用者自行決定**,QPyPack 的 GPL-3.0 協議不會約束或影響使用者打包後的程式。
|
||||
- 🌟 **Star 支援**:在 [GitHub](https://github.com/Qwejay/QPyPack) 上為專案點亮 Star。
|
||||
- 🐛 **反饋與建議**:提交 [Issue](https://github.com/Qwejay/QPyPack/issues) 反饋缺陷或提出改進需求。
|
||||
- ⚡ **贊助專案**:透過 [愛發電平台](https://www.ifdian.net/a/qwejay) 進行無償資助(支援微信 / 支付寶)。
|
||||
|
||||
Copyright (C) 2026 QwejayHuang.
|
||||
> *註:贊助屬於對開源社群專案的無償鼓勵,不涉及任何商業承諾或客製化開發服務。感謝所有支援開源社群建設的開發者!*
|
||||
|
||||
---
|
||||
|
||||
## 📄 開源許可 (License)
|
||||
|
||||
本專案基於 [GNU General Public License v3.0 (GPL-3.0)](../../LICENSE) 協議開源。
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **關於建置產物的版權說明**:
|
||||
> 使用 QPyPack 建置產生的最終應用程式與二進位產物,其**智慧財產權與開源授權完全由使用者自行決定**,QPyPack 的 GPL-3.0 許可協議不會對您的編譯產物施加傳染性約束。
|
||||
|
||||
<p align="right">Copyright (C) 2026 QwejayHuang.</p>
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "qpypack"
|
||||
version = "2.7.14"
|
||||
version = "2.8.0"
|
||||
description = "A cross-platform GUI packaging and compilation suite based on PyInstaller and Nuitka."
|
||||
readme = "README_EN.md"
|
||||
authors = [
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "الوصف:",
|
||||
"Desktop Application": "تطبيق سطح المكتب",
|
||||
"Detailed Mode": "الوضع المفصل",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "تم اكتشاف عدة سكربتات إدخال في المشروع. يرجى تحديد واحد للبناء:",
|
||||
"Directory": "الدليل",
|
||||
"Discovered via scanner ({count}): {pkgs}": "تم اكتشافه عبر الماسح ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "مساحة القرص منخفضة بشكل حرج: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "اتركه فارغًا للبحث التلقائي عن requirements.txt في الدليل الحالي",
|
||||
"Legacy macOS Compatible": "متوافق مع macOS القديم",
|
||||
"Lite Mode (Smaller size)": "الوضع الخفيف (حجم أصغر)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "تم تحميل المشروع: {name} | الإدخال: {entry}",
|
||||
"Loaded: {filename}": "تم التحميل: {filename}",
|
||||
"Locally Detected Pythons": "إصدارات بايثون المكتشفة محليًا",
|
||||
"Lock Core Dependencies": "قفل التبعيات الأساسية",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "تم تحميل البرنامج النصي. يمكنك سحب مجلدات الأصول أو ملفات البيانات مباشرة هنا لتجميعها.",
|
||||
"Select .pfx / .p12 certificate file": "حدد ملف الشهادة .pfx / .p12",
|
||||
"Select All": "تحديد الكل",
|
||||
"Select Main Entry Script": "حدد سكربت الإدخال الرئيسي",
|
||||
"Select Python Version to Download:": "حدد إصدار Python للتنزيل:",
|
||||
"Select shared directory...": "تحديد الدليل المشترك...",
|
||||
"Self-Signed Certificate (*.pfx)": "شهادة موقعة ذاتيًا (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] يحتوي الكود المصدري على أخطاء نحوية، تم إحباط التجميع:\n - الملف: {file}\n - النوع: {type}\n - السطر: السطر {line}\n - التفاصيل: {desc}\n\nنصيحة: يرجى التأكد من أن الكود المصدري يعمل محليًا قبل التعبئة.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] فشل تحليل بناء جملة الكود المصدري، تم إحباط البناء:\n - الملف: {file}\n - التفاصيل: {desc}\n\nنصيحة: هذا عادة ليس خطأ من أداة التعبئة.\nيرجى التأكد من أن [إصدار بايثون للبناء] الذي حددته يطابق الإصدار الذي استخدمته لـ [كتابة/اختبار الكود].\nاستخدام بناء جملة أحدث (مثل عامل الفظ :=، اتحادات الأنواع |، match-case) في بيئة بايثون أقدم سيؤدي إلى هذا الخطأ.\nنوصي بالانتقال إلى [إعدادات البناء] -> [المحرك] للتبديل إلى إصدار بايثون الصحيح.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] فشل تحليل بناء جملة الكود المصدري، تم إحباط البناء:\n - الملف: {file}\n - السطر: السطر {line}\n - التفاصيل: {desc}\n\nنصيحة: هذا عادة ليس خطأ من أداة التعبئة.\nيرجى التأكد من أن [إصدار بايثون للبناء] الذي اخترته يطابق الإصدار الذي استخدمته [لكتابة/اختبار الكود].\nاستخدام بناء جملة أحدث (مثل عامل الفظ :=، اتحادات الأنواع |، match-case) في بيئة بايثون أقدم سيؤدي إلى هذا الخطأ.\nنوصي بالانتقال إلى [إعدادات البناء] -> [المحرك] لتبديل إصدار بايثون الصحيح.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] يستورد السكربت الوحدة الأصلية '{mod}'. إذا فشل البناء، حاول سحب مجلد المشروع بأكمله هنا.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] تم اكتشاف وحدة 'multiprocessing'. تأكد من استدعاء 'multiprocessing.freeze_support()' تحت 'if __name__ == \"__main__\":' لمنع حلقات العمليات اللانهائية (قنابل الشوكة).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] استثناء تحليل AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] انتهت مهلة الأمر (>{timeout} ثانية)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] المشروع الهدف موجود في دليل مزامنة سحابية (مثل OneDrive/Dropbox). قد تؤدي المزامنة السحابية إلى قفل ملفات البناء مؤقتًا.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] انتهت مهلة الاتصال بخادم الطابع الزمني، يتم التوقيع السريع محليًا...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] تم اكتشاف استخدام '__file__'. في وضع الملف الواحد لـ PyInstaller، استخدم 'sys._MEIPASS' لتحديد موقع ملفات الموارد المضمنة بشكل موثوق!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nاكتمل تنفيذ البرنامج، اضغط Enter للخروج..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nاكتمل تنفيذ البرنامج، اضغط Enter للخروج...",
|
||||
"Package Mapping & Remediation": "تعيين الحزم والإصلاح"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Beschreibung:",
|
||||
"Desktop Application": "Desktop-Anwendung",
|
||||
"Detailed Mode": "Detaillierter Modus",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Mehrere Einstiegsskripte im Projekt erkannt. Bitte wählen Sie eines zum Erstellen aus:",
|
||||
"Directory": "Verzeichnis",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Per Scanner entdeckt ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Festplattenspeicher kritisch niedrig: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Leer lassen, um automatisch requirements.txt im aktuellen Verzeichnis zu suchen",
|
||||
"Legacy macOS Compatible": "Legacy macOS-kompatibel",
|
||||
"Lite Mode (Smaller size)": "Lite-Modus (kleinere Größe)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Geladenes Projekt: {name} | Einstieg: {entry}",
|
||||
"Loaded: {filename}": "Geladen: {filename}",
|
||||
"Locally Detected Pythons": "Lokal erkannte Pythons",
|
||||
"Lock Core Dependencies": "Kernabhängigkeiten sperren",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Skript geladen. Sie können Asset-Ordner oder Datendateien direkt hierher ziehen, um sie zu bündeln.",
|
||||
"Select .pfx / .p12 certificate file": "Wählen Sie .pfx / .p12 Zertifikatsdatei",
|
||||
"Select All": "Alle auswählen",
|
||||
"Select Main Entry Script": "Haupt-Einstiegsskript auswählen",
|
||||
"Select Python Version to Download:": "Python-Version zum Herunterladen auswählen:",
|
||||
"Select shared directory...": "Gemeinsames Verzeichnis auswählen...",
|
||||
"Self-Signed Certificate (*.pfx)": "Selbstsigniertes Zertifikat (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Der Quellcode enthält Syntaxfehler, Kompilierung abgebrochen:\n - Datei: {file}\n - Typ: {type}\n - Zeile: Zeile {line}\n - Detail: {desc}\n\nTipp: Bitte stellen Sie sicher, dass der Quellcode lokal ausgeführt werden kann, bevor Sie ihn verpacken.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Parsen des Quellcodes fehlgeschlagen, Build abgebrochen:\n - Datei: {file}\n - Detail: {desc}\n\nTipp: Dies ist normalerweise kein Fehler des Paketierungstools.\nBitte stellen Sie sicher, dass die ausgewählte [Build-Python-Version] mit der Version übereinstimmt, die Sie zum [Schreiben/Testen des Codes] verwendet haben.\nDie Verwendung neuerer Syntax (z.B. Walross-Operator :=, Typ-Unionen |, match-case) in einer älteren Python-Umgebung löst diesen Fehler aus.\nWir empfehlen, in den [Baueinstellungen] -> [Engine] zur korrekten Python-Version zu wechseln.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Die Syntaxanalyse des Quellcodes ist fehlgeschlagen, Build abgebrochen:\n - Datei: {file}\n - Zeile: Zeile {line}\n - Detail: {desc}\n\nTipp: Dies ist normalerweise KEIN Fehler des Verpackungstools.\nBitte stellen Sie sicher, dass die ausgewählte [Build-Python-Version] mit der Version übereinstimmt, die Sie zum [Schreiben/Testen des Codes] verwendet haben.\nDie Verwendung neuerer Syntax (z. B. Walross-Operator :=, Typ-Unionen |, match-case) in einer älteren Python-Umgebung führt zu diesem Fehler.\nWir empfehlen, unter [Buildeinstellungen] -> [Engine] zur korrekten Python-Version zu wechseln.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Das Skript importiert das übergeordnete Modul '{mod}'. Wenn der Build fehlschlägt, versuchen Sie, den gesamten Projektordner hierher zu ziehen.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] 'multiprocessing'-Modul erkannt. Stellen Sie sicher, dass 'multiprocessing.freeze_support()' unter 'if __name__ == \"__main__\":' aufgerufen wird, um Endlosschleifen (Fork-Bomben) zu verhindern.",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] AST-Analyse-Ausnahme: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Befehlszeitüberschreitung (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Zielprojekt befindet sich in einem Cloud-Sync-Verzeichnis (z.B. OneDrive/Dropbox). Cloud-Sync kann Build-Dateien vorübergehend sperren.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Zeitstempel-Server-Verbindung abgelaufen, lokale schnelle Signierung wird durchgeführt...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Verwendung von '__file__' erkannt. Im PyInstaller-Einzeldateimodus verwenden Sie 'sys._MEIPASS', um gebündelte Ressourcendateien zuverlässig zu finden!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nProgrammausführung abgeschlossen, drücken Sie die Eingabetaste zum Beenden..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nProgrammausführung abgeschlossen, drücken Sie die Eingabetaste zum Beenden...",
|
||||
"Package Mapping & Remediation": "Paketzuordnung & Fehlerbehebung"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Descripción:",
|
||||
"Desktop Application": "Aplicación de escritorio",
|
||||
"Detailed Mode": "Modo detallado",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Se detectaron múltiples scripts de entrada en el proyecto. Seleccione uno para compilar:",
|
||||
"Directory": "Directorio",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Descubierto mediante escáner ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Espacio en disco críticamente bajo: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Dejar en blanco para buscar automáticamente requirements.txt en el directorio actual",
|
||||
"Legacy macOS Compatible": "Compatible con macOS heredado",
|
||||
"Lite Mode (Smaller size)": "Modo ligero (tamaño más pequeño)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Proyecto cargado: {name} | Entrada: {entry}",
|
||||
"Loaded: {filename}": "Cargado: {filename}",
|
||||
"Locally Detected Pythons": "Pythons detectados localmente",
|
||||
"Lock Core Dependencies": "Bloquear dependencias principales",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Script cargado. Puede arrastrar carpetas de activos o archivos de datos directamente aquí para incluirlos.",
|
||||
"Select .pfx / .p12 certificate file": "Seleccionar archivo de certificado .pfx / .p12",
|
||||
"Select All": "Seleccionar Todo",
|
||||
"Select Main Entry Script": "Seleccionar script de entrada principal",
|
||||
"Select Python Version to Download:": "Seleccionar Versión de Python para Descargar:",
|
||||
"Select shared directory...": "Seleccionar directorio compartido...",
|
||||
"Self-Signed Certificate (*.pfx)": "Certificado Autofirmado (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] El código fuente contiene errores de sintaxis, compilación abortada:\n - Archivo: {file}\n - Tipo: {type}\n - Línea: Línea {line}\n - Detalle: {desc}\n\nConsejo: Asegúrese de que el código fuente se ejecute localmente antes de empaquetar.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Falló el análisis de sintaxis del código fuente, compilación abortada:\n - Archivo: {file}\n - Detalle: {desc}\n\nConsejo: Esto generalmente NO es un fallo de la herramienta de empaquetado.\nAsegúrese de que la [Versión de Python de compilación] seleccionada coincida con la versión que usó para [Escribir/Probar el código].\nUsar sintaxis más nueva (por ejemplo, operador morsa :=, uniones de tipos |, match-case) en un entorno Python más antiguo provocará este error.\nRecomendamos ir a [Configuración de compilación] -> [Motor] para cambiar a la versión correcta de Python.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Falló el análisis de sintaxis del código fuente, compilación abortada:\n - Archivo: {file}\n - Línea: Línea {line}\n - Detalle: {desc}\n\nConsejo: Esto generalmente NO es un fallo de la herramienta de empaquetado.\nAsegúrese de que la [Versión de Python de compilación] seleccionada coincida con la versión que usó para [Escribir/Probar el código].\nEl uso de sintaxis más nueva (por ejemplo, operador morsa :=, uniones de tipos |, match-case) en un entorno Python más antiguo provocará este error.\nRecomendamos ir a [Configuración de compilación] -> [Motor] para cambiar a la versión correcta de Python.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] El script importa el módulo padre '{mod}'. Si la compilación falla, intente arrastrar toda la carpeta del proyecto aquí.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Módulo 'multiprocessing' detectado. Asegúrese de que 'multiprocessing.freeze_support()' se llame dentro de 'if __name__ == \"__main__\":' para evitar bucles infinitos de procesos (fork bombs).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Excepción de análisis AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Tiempo de espera del comando agotado (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] El proyecto objetivo está en un directorio de sincronización en la nube (por ejemplo, OneDrive/Dropbox). La sincronización en la nube puede bloquear temporalmente los archivos de compilación.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Tiempo de espera agotado en la conexión al servidor de marcas de tiempo, realizando firma rápida local...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Se detectó el uso de '__file__'. En el modo de un solo archivo de PyInstaller, use 'sys._MEIPASS' para localizar de manera confiable los archivos de recursos empaquetados.",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nEjecución del programa completada, presione Enter para salir..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nEjecución del programa completada, presione Enter para salir...",
|
||||
"Package Mapping & Remediation": "Mapeo de paquetes y corrección"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Description :",
|
||||
"Desktop Application": "Application de bureau",
|
||||
"Detailed Mode": "Mode détaillé",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Plusieurs scripts d'entrée détectés dans le projet. Veuillez en sélectionner un à compiler :",
|
||||
"Directory": "Répertoire",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Découvert via le scanner ({count}) : {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Espace disque critique : {free:.1f} Go < {min:.1f} Go",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Laisser vide pour rechercher automatiquement requirements.txt dans le répertoire courant",
|
||||
"Legacy macOS Compatible": "Compatible macOS hérité",
|
||||
"Lite Mode (Smaller size)": "Mode léger (taille réduite)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Projet chargé : {name} | Entrée : {entry}",
|
||||
"Loaded: {filename}": "Chargé : {filename}",
|
||||
"Locally Detected Pythons": "Pythons détectés localement",
|
||||
"Lock Core Dependencies": "Verrouiller les dépendances principales",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Script chargé. Vous pouvez glisser des dossiers d'actifs ou des fichiers de données directement ici pour les regrouper.",
|
||||
"Select .pfx / .p12 certificate file": "Sélectionner le fichier de certificat .pfx / .p12",
|
||||
"Select All": "Tout sélectionner",
|
||||
"Select Main Entry Script": "Sélectionner le script d'entrée principal",
|
||||
"Select Python Version to Download:": "Sélectionner la version de Python à télécharger :",
|
||||
"Select shared directory...": "Sélectionner le répertoire partagé...",
|
||||
"Self-Signed Certificate (*.pfx)": "Certificat auto-signé (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Le code source contient des erreurs de syntaxe, compilation interrompue :\n - Fichier : {file}\n - Type : {type}\n - Ligne : Ligne {line}\n - Détail : {desc}\n\nAstuce : Veuillez vous assurer que le code source s'exécute localement avant l'empaquetage.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] L'analyse syntaxique du code source a échoué, build interrompu :\n - Fichier : {file}\n - Détail : {desc}\n\nAstuce : Ce n'est généralement pas une faute de l'outil d'empaquetage.\nAssurez-vous que la [Version Python de build] sélectionnée correspond à celle utilisée pour [Écrire/Tester le code].\nL'utilisation d'une syntaxe plus récente (par exemple, opérateur morse :=, unions de types |, match-case) dans un environnement Python plus ancien déclenchera cette erreur.\nNous recommandons d'aller dans [Paramètres de build] -> [Moteur] pour passer à la version Python correcte.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] L'analyse syntaxique du code source a échoué, construction interrompue :\n - Fichier : {file}\n - Ligne : Ligne {line}\n - Détail : {desc}\n\nAstuce : Ce n'est généralement PAS une faute de l'outil d'empaquetage.\nVeuillez vous assurer que la [Version Python de construction] que vous avez sélectionnée correspond à celle utilisée pour [Écrire/Tester le code].\nL'utilisation d'une syntaxe plus récente (par exemple, l'opérateur morse :=, les unions de types |, match-case) dans un environnement Python plus ancien déclenchera cette erreur.\nNous recommandons d'aller dans [Paramètres de construction] -> [Moteur] pour passer à la version Python correcte.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Le script importe le module parent '{mod}'. Si la compilation échoue, essayez de glisser le dossier du projet entier ici.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Module 'multiprocessing' détecté. Assurez-vous que 'multiprocessing.freeze_support()' est appelé sous 'if __name__ == \"__main__\":' pour éviter les boucles de processus infinies (bombes de fork).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Exception d'analyse AST : {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Délai d'attente de la commande dépassé (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Le projet cible se trouve dans un répertoire de synchronisation cloud (par ex. OneDrive/Dropbox). La synchronisation cloud peut temporairement verrouiller les fichiers de construction.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Délai d'attente dépassé pour le serveur d'horodatage, signature rapide locale en cours...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Utilisation de '__file__' détectée. En mode fichier unique PyInstaller, utilisez 'sys._MEIPASS' pour localiser de manière fiable les fichiers de ressources inclus !",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nExécution du programme terminée, appuyez sur Entrée pour quitter..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nExécution du programme terminée, appuyez sur Entrée pour quitter...",
|
||||
"Package Mapping & Remediation": "Mappage de paquets et correction"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Descrizione:",
|
||||
"Desktop Application": "Applicazione desktop",
|
||||
"Detailed Mode": "Modalità dettagliata",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Rilevati più script di ingresso nel progetto. Selezionane uno da compilare:",
|
||||
"Directory": "Directory",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Scoperte tramite scanner ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Spazio su disco criticamente basso: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Lasciare vuoto per cercare automaticamente requirements.txt nella directory corrente",
|
||||
"Legacy macOS Compatible": "Compatibile con macOS legacy",
|
||||
"Lite Mode (Smaller size)": "Modalità leggera (dimensioni ridotte)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Progetto caricato: {name} | Ingresso: {entry}",
|
||||
"Loaded: {filename}": "Caricato: {filename}",
|
||||
"Locally Detected Pythons": "Python rilevati localmente",
|
||||
"Lock Core Dependencies": "Blocca dipendenze principali",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Script caricato. Puoi trascinare qui direttamente le cartelle di asset o i file di dati per includerli.",
|
||||
"Select .pfx / .p12 certificate file": "Seleziona file certificato .pfx / .p12",
|
||||
"Select All": "Seleziona Tutto",
|
||||
"Select Main Entry Script": "Seleziona script di ingresso principale",
|
||||
"Select Python Version to Download:": "Seleziona Versione Python da Scaricare:",
|
||||
"Select shared directory...": "Seleziona directory condivisa...",
|
||||
"Self-Signed Certificate (*.pfx)": "Certificato Auto-Firmato (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Il codice sorgente contiene errori di sintassi, compilazione interrotta:\n - File: {file}\n - Tipo: {type}\n - Riga: Riga {line}\n - Dettaglio: {desc}\n\nSuggerimento: assicurarsi che il codice sorgente venga eseguito localmente prima dell'impacchettamento.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Analisi della sintassi del codice sorgente fallita, build interrotta:\n - File: {file}\n - Dettaglio: {desc}\n\nSuggerimento: Di solito NON è un difetto dello strumento di packaging.\nAssicurati che la [Versione Python di build] selezionata corrisponda alla versione usata per [Scrivere/Testare il codice].\nL'uso di sintassi più recente (es. operatore tricheco :=, unioni di tipi |, match-case) in un ambiente Python più vecchio attiverà questo errore.\nTi consigliamo di andare in [Impostazioni di build] -> [Motore] per passare alla versione Python corretta.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Analisi della sintassi del codice sorgente non riuscita, build interrotta:\n - File: {file}\n - Riga: Riga {line}\n - Dettaglio: {desc}\n\nSuggerimento: di solito NON è un difetto dello strumento di impacchettamento.\nAssicurarsi che la [Versione Python di build] selezionata corrisponda alla versione utilizzata per [Scrivere/Testare il codice].\nL'uso di sintassi più recente (ad esempio operatore tricheco :=, unioni di tipi |, match-case) in un ambiente Python più vecchio attiverà questo errore.\nSi consiglia di andare su [Impostazioni di build] -> [Motore] per passare alla versione Python corretta.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Lo script importa il modulo padre '{mod}'. Se la compilazione fallisce, prova a trascinare qui l'intera cartella del progetto.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Modulo 'multiprocessing' rilevato. Assicurarsi che 'multiprocessing.freeze_support()' venga chiamato sotto 'if __name__ == \"__main__\":' per prevenire cicli di processo infiniti (fork bomb).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Eccezione durante l'analisi AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Timeout del comando (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Il progetto di destinazione si trova in una directory di sincronizzazione cloud (es. OneDrive/Dropbox). La sincronizzazione cloud potrebbe bloccare temporaneamente i file di build.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Timeout della connessione al server timestamp, esecuzione di firma rapida locale...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Rilevato uso di '__file__'. In modalità One-File di PyInstaller, usa 'sys._MEIPASS' per individuare in modo affidabile i file di risorse inclusi!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nEsecuzione del programma completata, premere Invio per uscire..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nEsecuzione del programma completata, premere Invio per uscire...",
|
||||
"Package Mapping & Remediation": "Mappatura pacchetti e correzione"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "説明::",
|
||||
"Desktop Application": "デスクトップアプリケーション",
|
||||
"Detailed Mode": "詳細モード",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "プロジェクト内に複数のエントリスクリプトが検出されました。ビルドするものを選択してください:",
|
||||
"Directory": "ディレクトリ",
|
||||
"Discovered via scanner ({count}): {pkgs}": "スキャナーで検出({count}):{pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "ディスク容量が不足しています: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -147,6 +148,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "空白のままにすると現在のディレクトリの requirements.txt を自動検索します",
|
||||
"Legacy macOS Compatible": "レガシー macOS 互換",
|
||||
"Lite Mode (Smaller size)": "ライトモード(サイズ小)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "プロジェクトを読み込みました: {name} | エントリ: {entry}",
|
||||
"Loaded: {filename}": "読み込み済み: {filename}",
|
||||
"Locally Detected Pythons": "ローカルで検出された Python",
|
||||
"Lock Core Dependencies": "コア依存関係をロック",
|
||||
@@ -249,6 +251,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "スクリプトが読み込まれました。アセットフォルダやデータファイルをここに直接ドラッグしてバンドルできます。",
|
||||
"Select .pfx / .p12 certificate file": ".pfx / .p12 証明書ファイルを選択",
|
||||
"Select All": "すべて選択",
|
||||
"Select Main Entry Script": "メインエントリスクリプトを選択",
|
||||
"Select Python Version to Download:": "ダウンロードする Python バージョンを選択:",
|
||||
"Select shared directory...": "共有ディレクトリを選択...",
|
||||
"Self-Signed Certificate (*.pfx)": "自己署名証明書 (*.pfx)",
|
||||
@@ -376,6 +379,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] ソースコードに構文エラーが含まれているため、コンパイルを中止しました:\n - ファイル: {file}\n - 種類: {type}\n - 行: {line}行目\n - 詳細: {desc}\n\nヒント: パッケージ化する前に、ソースコードがローカルで実行できることを確認してください。",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] ソースコードの構文解析に失敗しました。ビルドを中止します:\n - ファイル: {file}\n - 詳細: {desc}\n\nヒント: これは通常、パッケージングツールの欠陥ではありません。\n選択した[ビルドPythonバージョン]が、コードの[記述/テスト]に使用したバージョンと一致していることを確認してください。\n新しい構文(例: セイウチ演算子 :=、型ユニオン |、match-case)を古いPython環境で使用すると、このエラーが発生します。\n[ビルド設定] -> [エンジン]で正しいPythonバージョンに切り替えることをお勧めします。",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] ソースコードの構文解析に失敗したため、ビルドを中止しました:\n - ファイル: {file}\n - 行: {line}行目\n - 詳細: {desc}\n\nヒント: これは通常、パッケージ化ツールの欠陥ではありません。\n選択した[ビルドPythonバージョン]が、コードの[作成/テスト]に使用したバージョンと一致していることを確認してください。\n古いPython環境で新しい構文(例: セイウチ演算子 :=、型ユニオン |、match-case)を使用すると、このエラーが発生します。\n[ビルド設定] -> [エンジン]で正しいPythonバージョンに切り替えることをお勧めします。",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] スクリプトが親モジュール '{mod}' をインポートしています。ビルドに失敗する場合は、プロジェクトフォルダ全体をここにドラッグしてみてください。",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] 'multiprocessing'モジュールが検出されました。無限プロセスループ(フォーク爆弾)を防ぐために、'if __name__ == \"__main__\":'の下で'multiprocessing.freeze_support()'を呼び出してください。",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] AST解析例外: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] コマンドがタイムアウトしました (> {timeout}秒)",
|
||||
@@ -404,5 +408,7 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] ターゲットプロジェクトはクラウド同期ディレクトリ (例: OneDrive/Dropbox) にあります。クラウド同期によりビルドファイルが一時的にロックされる可能性があります。",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] タイムスタンプサーバーへの接続がタイムアウトしました。ローカル高速署名を実行します...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] '__file__' の使用が検出されました。PyInstallerのワンファイルモードでは、バンドルされたリソースファイルを確実に特定するために 'sys._MEIPASS' を使用してください!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nプログラムの実行が完了しました。終了するにはEnterキーを押してください..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nプログラムの実行が完了しました。終了するにはEnterキーを押してください...",
|
||||
"Generate": "生成",
|
||||
"Package Mapping & Remediation": "パッケージマッピングと修復"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "설명:",
|
||||
"Desktop Application": "데스크톱 애플리케이션",
|
||||
"Detailed Mode": "상세 모드",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "프로젝트에서 여러 진입 스크립트가 감지되었습니다. 빌드할 항목을 선택하세요:",
|
||||
"Directory": "디렉터리",
|
||||
"Discovered via scanner ({count}): {pkgs}": "스캐너를 통해 발견됨 ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "디스크 공간이 매우 부족합니다: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "비워 두면 현재 디렉터리에서 requirements.txt 자동 검색",
|
||||
"Legacy macOS Compatible": "레거시 macOS 호환",
|
||||
"Lite Mode (Smaller size)": "라이트 모드 (더 작은 크기)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "로드된 프로젝트: {name} | 진입점: {entry}",
|
||||
"Loaded: {filename}": "로드됨: {filename}",
|
||||
"Locally Detected Pythons": "로컬에서 감지된 Python",
|
||||
"Lock Core Dependencies": "핵심 종속성 잠금",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "스크립트가 로드되었습니다. 에셋 폴더나 데이터 파일을 여기에 직접 끌어다 놓아 번들할 수 있습니다.",
|
||||
"Select .pfx / .p12 certificate file": ".pfx / .p12 인증서 파일 선택",
|
||||
"Select All": "모두 선택",
|
||||
"Select Main Entry Script": "메인 진입 스크립트 선택",
|
||||
"Select Python Version to Download:": "다운로드할 Python 버전 선택:",
|
||||
"Select shared directory...": "공유 디렉터리 선택...",
|
||||
"Self-Signed Certificate (*.pfx)": "자체 서명 인증서 (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] 소스 코드에 구문 오류가 있어 컴파일이 중단되었습니다:\n - 파일: {file}\n - 유형: {type}\n - 줄: {line}번째 줄\n - 세부 정보: {desc}\n\n팁: 패키징 전에 소스 코드가 로컬에서 실행되는지 확인하세요.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] 소스 코드 구문 분석에 실패하여 빌드가 중단되었습니다:\n - 파일: {file}\n - 세부 정보: {desc}\n\n팁: 이는 일반적으로 패키징 도구의 문제가 아닙니다.\n선택한 [빌드 Python 버전]이 코드를 [작성/테스트]할 때 사용한 버전과 일치하는지 확인하세요.\n이전 Python 환경에서 최신 구문(예: 바다코끼리 연산자 :=, 타입 유니온 |, match-case)을 사용하면 이 오류가 발생합니다.\n[빌드 설정] -> [엔진]으로 이동하여 올바른 Python 버전으로 전환하는 것이 좋습니다.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] 소스 코드 구문 분석에 실패하여 빌드가 중단되었습니다:\n - 파일: {file}\n - 줄: {line}번째 줄\n - 세부 정보: {desc}\n\n팁: 이는 일반적으로 패키징 도구의 문제가 아닙니다.\n선택한 [빌드 Python 버전]이 코드를 [작성/테스트]할 때 사용한 버전과 일치하는지 확인하세요.\n이전 Python 환경에서 최신 구문(예: 바다코끼리 연산자 :=, 타입 유니온 |, match-case)을 사용하면 이 오류가 발생합니다.\n[빌드 설정] -> [엔진]에서 올바른 Python 버전으로 전환하는 것을 권장합니다.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] 스크립트가 상위 모듈 '{mod}'을(를) 가져옵니다. 빌드가 실패하면 전체 프로젝트 폴더를 여기로 끌어다 놓으세요.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] 'multiprocessing' 모듈이 감지되었습니다. 무한 프로세스 루프(포크 폭탄)를 방지하려면 'if __name__ == \"__main__\":' 아래에서 'multiprocessing.freeze_support()'를 호출하세요.",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] AST 분석 예외: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] 명령 시간 초과(>{timeout}초)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] 대상 프로젝트가 클라우드 동기화 디렉터리(예: OneDrive/Dropbox)에 있습니다. 클라우드 동기화로 인해 빌드 파일이 일시적으로 잠길 수 있습니다.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] 타임스탬프 서버 연결 시간이 초과되어 로컬 빠른 서명을 수행합니다...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] '__file__' 사용이 감지되었습니다. PyInstaller 원파일 모드에서는 'sys._MEIPASS'를 사용하여 번들 리소스 파일을 안정적으로 찾으십시오!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\n프로그램 실행이 완료되었습니다. 종료하려면 Enter를 누르십시오..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\n프로그램 실행이 완료되었습니다. 종료하려면 Enter를 누르십시오...",
|
||||
"Package Mapping & Remediation": "패키지 매핑 및 수정"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Beschrijving:",
|
||||
"Desktop Application": "Desktoptoepassing",
|
||||
"Detailed Mode": "Gedetailleerde modus",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Meerdere entry-scripts gedetecteerd in het project. Selecteer er een om te bouwen:",
|
||||
"Directory": "Map",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Gevonden via scanner ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Schijfruimte kritiek laag: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Laat leeg om automatisch requirements.txt in de huidige map te zoeken",
|
||||
"Legacy macOS Compatible": "Legacy macOS-compatibel",
|
||||
"Lite Mode (Smaller size)": "Lite-modus (kleiner formaat)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Project geladen: {name} | Entry: {entry}",
|
||||
"Loaded: {filename}": "Geladen: {filename}",
|
||||
"Locally Detected Pythons": "Lokaal gedetecteerde Pythons",
|
||||
"Lock Core Dependencies": "Kernafhankelijkheden vergrendelen",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Script geladen. U kunt assetmappen of gegevensbestanden hier direct naartoe slepen om ze te bundelen.",
|
||||
"Select .pfx / .p12 certificate file": "Selecteer .pfx / .p12 certificaatbestand",
|
||||
"Select All": "Alles selecteren",
|
||||
"Select Main Entry Script": "Selecteer hoofd-entry-script",
|
||||
"Select Python Version to Download:": "Selecteer Python-versie om te downloaden:",
|
||||
"Select shared directory...": "Selecteer gedeelde map...",
|
||||
"Self-Signed Certificate (*.pfx)": "Zelfondertekend certificaat (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Broncode bevat syntaxfouten, compilatie afgebroken:\n - Bestand: {file}\n - Type: {type}\n - Regel: Regel {line}\n - Detail: {desc}\n\nTip: Zorg ervoor dat de broncode lokaal werkt voordat u deze verpakt.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Broncode-syntaxparsing mislukt, bouwen afgebroken:\n - Bestand: {file}\n - Detail: {desc}\n\nTip: Dit is meestal GEEN fout van het verpakkingsprogramma.\nZorg ervoor dat de [Bouw Python-versie] die u selecteert overeenkomt met de versie die u gebruikte om de code te [schrijven/testen].\nHet gebruik van nieuwere syntax (bijv. walrus-operator :=, type-unies |, match-case) in een oudere Python-omgeving zal deze fout veroorzaken.\nWe raden aan om naar [Bouwinstellingen] -> [Engine] te gaan om over te schakelen naar de juiste Python-versie.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Parsen van broncodesyntax mislukt, build afgebroken:\n - Bestand: {file}\n - Regel: Regel {line}\n - Detail: {desc}\n\nTip: Dit is meestal GEEN fout van het verpakkingsprogramma.\nZorg ervoor dat de [Build Python-versie] die u selecteert overeenkomt met de versie die u gebruikte om de code te [schrijven/testen].\nHet gebruik van nieuwere syntax (bijv. walrus-operator :=, type-unies |, match-case) in een oudere Python-omgeving veroorzaakt deze fout.\nWe raden aan om naar [Build-instellingen] -> [Engine] te gaan om over te schakelen naar de juiste Python-versie.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Het script importeert de bovenliggende module '{mod}'. Als de build mislukt, probeer dan de hele projectmap hierheen te slepen.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] 'multiprocessing'-module gedetecteerd. Zorg ervoor dat 'multiprocessing.freeze_support()' wordt aangeroepen onder 'if __name__ == \"__main__\":' om oneindige processlussen (fork-bommen) te voorkomen.",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] AST-analyse-uitzondering: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Commandotime-out (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Doelproject bevindt zich in een Cloud Sync-map (bijv. OneDrive/Dropbox). Cloud sync kan buildbestanden tijdelijk vergrendelen.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Tijdstempelserververbinding is verlopen, lokale snelle ondertekening wordt uitgevoerd...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Gebruik van '__file__' gedetecteerd. In PyInstaller One-File modus, gebruik 'sys._MEIPASS' om gebundelde bronbestanden betrouwbaar te lokaliseren!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nProgramma-uitvoering voltooid, druk op Enter om af te sluiten..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nProgramma-uitvoering voltooid, druk op Enter om af te sluiten...",
|
||||
"Package Mapping & Remediation": "Pakkettoewijzing & Herstel"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Opis:",
|
||||
"Desktop Application": "Aplikacja desktopowa",
|
||||
"Detailed Mode": "Tryb szczegółowy",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Wykryto wiele skryptów wejściowych w projekcie. Wybierz jeden do zbudowania:",
|
||||
"Directory": "Katalog",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Wykryto przez skaner ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Krytycznie mało miejsca na dysku: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Pozostaw puste, aby automatycznie wyszukać requirements.txt w bieżącym katalogu",
|
||||
"Legacy macOS Compatible": "Zgodność z legacy macOS",
|
||||
"Lite Mode (Smaller size)": "Tryb lekki (mniejszy rozmiar)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Załadowano projekt: {name} | Wejście: {entry}",
|
||||
"Loaded: {filename}": "Załadowano: {filename}",
|
||||
"Locally Detected Pythons": "Lokalnie wykryte Pythony",
|
||||
"Lock Core Dependencies": "Zablokuj podstawowe zależności",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Skrypt załadowany. Możesz przeciągnąć foldery zasobów lub pliki danych bezpośrednio tutaj, aby je spakować.",
|
||||
"Select .pfx / .p12 certificate file": "Wybierz plik certyfikatu .pfx / .p12",
|
||||
"Select All": "Zaznacz wszystko",
|
||||
"Select Main Entry Script": "Wybierz główny skrypt wejściowy",
|
||||
"Select Python Version to Download:": "Wybierz wersję Pythona do pobrania:",
|
||||
"Select shared directory...": "Wybierz katalog współdzielony...",
|
||||
"Self-Signed Certificate (*.pfx)": "Certyfikat self-signed (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Kod źródłowy zawiera błędy składni, kompilacja przerwana:\n - Plik: {file}\n - Typ: {type}\n - Linia: Linia {line}\n - Szczegóły: {desc}\n\nWskazówka: Upewnij się, że kod źródłowy działa lokalnie przed pakowaniem.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Analiza składni kodu źródłowego nie powiodła się, budowanie przerwane:\n - Plik: {file}\n - Szczegóły: {desc}\n\nWskazówka: To zwykle NIE jest wina narzędzia do pakowania.\nUpewnij się, że wybrana [Wersja Pythona do budowania] odpowiada wersji, której używasz do [Pisania/Testowania kodu].\nUżycie nowszej składni (np. operator morsa :=, unie typów |, match-case) w starszym środowisku Pythona spowoduje ten błąd.\nZalecamy przejście do [Ustawienia budowania] -> [Silnik], aby przełączyć na właściwą wersję Pythona.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Analiza składni kodu źródłowego nie powiodła się, budowanie przerwane:\n - Plik: {file}\n - Linia: Linia {line}\n - Szczegóły: {desc}\n\nWskazówka: To zwykle NIE jest wina narzędzia do pakowania.\nUpewnij się, że wybrana [Wersja Pythona do budowania] odpowiada wersji użytej do [Pisania/Testowania kodu].\nUżycie nowszej składni (np. operator morsa :=, unie typów |, match-case) w starszym środowisku Python spowoduje ten błąd.\nZalecamy przejście do [Ustawienia budowania] -> [Silnik], aby przełączyć się na właściwą wersję Pythona.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Skrypt importuje moduł nadrzędny '{mod}'. Jeśli budowanie nie powiedzie się, spróbuj przeciągnąć cały folder projektu tutaj.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Wykryto moduł 'multiprocessing'. Upewnij się, że 'multiprocessing.freeze_support()' jest wywoływane w bloku 'if __name__ == \"__main__\":', aby zapobiec nieskończonym pętlom procesów (bomby fork).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Wyjątek analizy AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Przekroczono limit czasu polecenia (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Projekt docelowy znajduje się w katalogu synchronizacji chmurowej (np. OneDrive/Dropbox). Synchronizacja chmurowa może tymczasowo blokować pliki budowania.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Przekroczono limit czasu połączenia z serwerem znaczników czasu, wykonywanie lokalnego szybkiego podpisywania...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Wykryto użycie '__file__'. W trybie jednego pliku PyInstaller, użyj 'sys._MEIPASS', aby niezawodnie zlokalizować dołączone pliki zasobów!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nWykonywanie programu zakończone, naciśnij Enter, aby wyjść..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nWykonywanie programu zakończone, naciśnij Enter, aby wyjść...",
|
||||
"Package Mapping & Remediation": "Mapowanie pakietów i naprawa"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Descrição:",
|
||||
"Desktop Application": "Aplicativo de Desktop",
|
||||
"Detailed Mode": "Modo Detalhado",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Detectados múltiplos scripts de entrada no projeto. Selecione um para compilar:",
|
||||
"Directory": "Diretório",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Descoberto via scanner ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Espaço em disco criticamente baixo: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Deixe em branco para procurar automaticamente requirements.txt no diretório atual",
|
||||
"Legacy macOS Compatible": "Compatível com macOS Legado",
|
||||
"Lite Mode (Smaller size)": "Modo Leve (Tamanho menor)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Projeto carregado: {name} | Entrada: {entry}",
|
||||
"Loaded: {filename}": "Carregado: {filename}",
|
||||
"Locally Detected Pythons": "Pythons Detectados Localmente",
|
||||
"Lock Core Dependencies": "Bloquear Dependências Principais",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Script carregado. Você pode arrastar pastas de assets ou arquivos de dados diretamente aqui para empacotá-los.",
|
||||
"Select .pfx / .p12 certificate file": "Selecionar arquivo de certificado .pfx / .p12",
|
||||
"Select All": "Selecionar Tudo",
|
||||
"Select Main Entry Script": "Selecionar Script de Entrada Principal",
|
||||
"Select Python Version to Download:": "Selecione a Versão do Python para Baixar:",
|
||||
"Select shared directory...": "Selecionar diretório compartilhado...",
|
||||
"Self-Signed Certificate (*.pfx)": "Certificado Autoassinado (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] O código-fonte contém erros de sintaxe, compilação abortada:\n - Arquivo: {file}\n - Tipo: {type}\n - Linha: Linha {line}\n - Detalhe: {desc}\n\nDica: Certifique-se de que o código-fonte seja executado localmente antes de empacotar.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Falha na análise de sintaxe do código-fonte, build abortado:\n - Arquivo: {file}\n - Detalhe: {desc}\n\nDica: Isso geralmente NÃO é um defeito da ferramenta de empacotamento.\nCertifique-se de que a [Versão do Python de Build] selecionada corresponde à versão usada para [Escrever/Testar o Código].\nUsar sintaxe mais nova (ex.: operador walrus :=, uniões de tipos |, match-case) em um ambiente Python mais antigo acionará este erro.\nRecomendamos ir para [Configurações de Build] -> [Mecanismo] para mudar para a versão correta do Python.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Falha na análise de sintaxe do código-fonte, compilação abortada:\n - Arquivo: {file}\n - Linha: Linha {line}\n - Detalhe: {desc}\n\nDica: Isso geralmente NÃO é uma falha da ferramenta de empacotamento.\nCertifique-se de que a [Versão do Python de Compilação] selecionada corresponda à versão usada para [Escrever/Testar o Código].\nO uso de sintaxe mais recente (por exemplo, operador walrus :=, uniões de tipos |, match-case) em um ambiente Python mais antigo acionará este erro.\nRecomendamos ir para [Configurações de Compilação] -> [Mecanismo] para alternar para a versão correta do Python.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] O script importa o módulo pai '{mod}'. Se a compilação falhar, tente arrastar a pasta inteira do projeto para cá.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Módulo 'multiprocessing' detectado. Certifique-se de que 'multiprocessing.freeze_support()' seja chamado sob 'if __name__ == \"__main__\":' para evitar loops infinitos de processos (fork bombs).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Exceção na análise AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Tempo limite do comando excedido (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] O projeto alvo está em um diretório de sincronização em nuvem (ex.: OneDrive/Dropbox). A sincronização em nuvem pode bloquear temporariamente os arquivos de compilação.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] O servidor de carimbo de tempo expirou, realizando assinatura local rápida...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Uso de '__file__' detectado. No modo One-File do PyInstaller, use 'sys._MEIPASS' para localizar com confiabilidade os arquivos de recursos empacotados!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nExecução do programa concluída, pressione Enter para sair..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nExecução do programa concluída, pressione Enter para sair...",
|
||||
"Package Mapping & Remediation": "Mapeamento de pacotes e correção"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Описание:",
|
||||
"Desktop Application": "Настольное приложение",
|
||||
"Detailed Mode": "Подробный режим",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "В проекте обнаружено несколько входных скриптов. Выберите один для сборки:",
|
||||
"Directory": "Каталог",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Обнаружено сканером ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Критически мало места на диске: {free:.1f}ГБ < {min:.1f}ГБ",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Оставьте пустым для автоматического поиска requirements.txt в текущем каталоге",
|
||||
"Legacy macOS Compatible": "Совместимость с устаревшими macOS",
|
||||
"Lite Mode (Smaller size)": "Облегченный режим (меньший размер)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Загружен проект: {name} | Вход: {entry}",
|
||||
"Loaded: {filename}": "Загружено: {filename}",
|
||||
"Locally Detected Pythons": "Локально обнаруженные Python",
|
||||
"Lock Core Dependencies": "Заблокировать основные зависимости",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Скрипт загружен. Вы можете перетащить папки с ресурсами или файлы данных прямо сюда, чтобы включить их в пакет.",
|
||||
"Select .pfx / .p12 certificate file": "Выберите файл сертификата .pfx / .p12",
|
||||
"Select All": "Выбрать все",
|
||||
"Select Main Entry Script": "Выберите основной входной скрипт",
|
||||
"Select Python Version to Download:": "Выберите версию Python для загрузки:",
|
||||
"Select shared directory...": "Выберите общий каталог...",
|
||||
"Self-Signed Certificate (*.pfx)": "Самозаверяющий сертификат (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Исходный код содержит синтаксические ошибки, компиляция прервана:\n - Файл: {file}\n - Тип: {type}\n - Строка: строка {line}\n - Подробности: {desc}\n\nСовет. Убедитесь, что исходный код запускается локально перед упаковкой.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Не удалось выполнить синтаксический анализ исходного кода, сборка прервана:\n - Файл: {file}\n - Подробности: {desc}\n\nСовет: Обычно это не вина инструмента упаковки.\nУбедитесь, что выбранная [Версия Python для сборки] соответствует версии, которую вы использовали для [Написания/Тестирования кода].\nИспользование нового синтаксиса (например, оператора моржа :=, объединения типов |, match-case) в более старой среде Python вызовет эту ошибку.\nРекомендуем перейти в [Настройки сборки] -> [Движок], чтобы переключиться на правильную версию Python.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Не удалось выполнить синтаксический анализ исходного кода, сборка прервана:\n - Файл: {file}\n - Строка: строка {line}\n - Подробности: {desc}\n\nСовет. Обычно это НЕ ошибка инструмента упаковки.\nУбедитесь, что выбранная [Версия Python для сборки] соответствует версии, которую вы использовали для [Написания/Тестирования кода].\nИспользование нового синтаксиса (например, оператор моржа :=, объединение типов |, match-case) в более старой среде Python вызовет эту ошибку.\nРекомендуем перейти в [Настройки сборки] -> [Движок], чтобы переключиться на правильную версию Python.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Скрипт импортирует родительский модуль '{mod}'. Если сборка не удается, попробуйте перетащить сюда всю папку проекта.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Обнаружен модуль 'multiprocessing'. Убедитесь, что 'multiprocessing.freeze_support()' вызывается внутри 'if __name__ == \"__main__\":', чтобы предотвратить бесконечные циклы процессов (форк-бомбы).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Исключение при анализе AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Тайм-аут команды (>{timeout}с)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Целевой проект находится в каталоге облачной синхронизации (например, OneDrive/Dropbox). Облачная синхронизация может временно блокировать файлы сборки.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Истекло время ожидания соединения с сервером меток времени, выполняется локальная быстрая подпись...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Обнаружено использование '__file__'. В однофайловом режиме PyInstaller используйте 'sys._MEIPASS' для надежного поиска встроенных файлов ресурсов!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nВыполнение программы завершено, нажмите Enter для выхода..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nВыполнение программы завершено, нажмите Enter для выхода...",
|
||||
"Package Mapping & Remediation": "Сопоставление пакетов и исправление"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "คำอธิบาย:",
|
||||
"Desktop Application": "แอปพลิเคชันเดสก์ท็อป",
|
||||
"Detailed Mode": "โหมดรายละเอียด",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "ตรวจพบสคริปต์ entry หลายตัวในโปรเจกต์ โปรดเลือกหนึ่งรายการเพื่อสร้าง:",
|
||||
"Directory": "ไดเรกทอรี",
|
||||
"Discovered via scanner ({count}): {pkgs}": "ค้นพบผ่านสแกนเนอร์ ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "พื้นที่ดิสก์เหลือน้อยมาก: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "เว้นว่างไว้เพื่อค้นหา requirements.txt ในไดเรกทอรีปัจจุบันอัตโนมัติ",
|
||||
"Legacy macOS Compatible": "เข้ากันได้กับ macOS รุ่นเก่า",
|
||||
"Lite Mode (Smaller size)": "โหมดไลต์ (ขนาดเล็กลง)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "โหลดโปรเจกต์: {name} | Entry: {entry}",
|
||||
"Loaded: {filename}": "โหลดแล้ว: {filename}",
|
||||
"Locally Detected Pythons": "Python ที่ตรวจพบในเครื่อง",
|
||||
"Lock Core Dependencies": "ล็อก Core Dependencies",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "โหลดสคริปต์แล้ว คุณสามารถลากโฟลเดอร์ทรัพยากรหรือไฟล์ข้อมูลมาที่นี่เพื่อรวมเข้าด้วยกัน",
|
||||
"Select .pfx / .p12 certificate file": "เลือกไฟล์ใบรับรอง .pfx / .p12",
|
||||
"Select All": "เลือกทั้งหมด",
|
||||
"Select Main Entry Script": "เลือกสคริปต์ Entry หลัก",
|
||||
"Select Python Version to Download:": "เลือกเวอร์ชัน Python ที่จะดาวน์โหลด:",
|
||||
"Select shared directory...": "เลือกไดเรกทอรีที่ใช้ร่วมกัน...",
|
||||
"Self-Signed Certificate (*.pfx)": "ใบรับรองที่เซ็นชื่อเอง (*.pfx)",
|
||||
@@ -375,6 +378,7 @@
|
||||
"[SUCCESS] Compilation completed, output path: {path}": "[SUCCESS] การคอมไพล์เสร็จสมบูรณ์ พาธเอาต์พุต: {path}",
|
||||
"[SUCCESS] Digital signature applied successfully!": "[SUCCESS] ใช้ลายเซ็นดิจิทัลสำเร็จ!",
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] ซอร์สโค้ดมีข้อผิดพลาดทางไวยากรณ์ การคอมไพล์ถูกยกเลิก:\n - ไฟล์: {file}\n - ประเภท: {type}\n - บรรทัด: บรรทัดที่ {line}\n - รายละเอียด: {desc}\n\nเคล็ดลับ: โปรดตรวจสอบให้แน่ใจว่าซอร์สโค้ดทำงานได้ในเครื่องก่อนแพ็กเกจ",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] สคริปต์นำเข้าโมดูลหลัก '{mod}' หากการสร้างล้มเหลว ให้ลองลากโฟลเดอร์โปรเจกต์ทั้งหมดมาที่นี่",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] ตรวจพบโมดูล 'multiprocessing' โปรดตรวจสอบให้แน่ใจว่าได้เรียก 'multiprocessing.freeze_support()' ภายใต้ 'if __name__ == \"__main__\":' เพื่อป้องกันการวนซ้ำของกระบวนการไม่รู้จบ (fork bombs)",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] ข้อยกเว้นการวิเคราะห์ AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] คำสั่งหมดเวลา (> {timeout} วินาที)",
|
||||
@@ -403,5 +407,8 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] โปรเจกต์เป้าหมายอยู่ในไดเรกทอรี Cloud Sync (เช่น OneDrive/Dropbox) การซิงก์คลาวด์อาจล็อกไฟล์ build ชั่วคราว",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] การเชื่อมต่อกับเซิร์ฟเวอร์ timestamp หมดเวลา กำลังลงนามแบบเร็วในเครื่อง...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] ตรวจพบการใช้ '__file__' ในโหมด One-File ของ PyInstaller ควรใช้ 'sys._MEIPASS' เพื่อค้นหาไฟล์ทรัพยากรที่รวมอยู่ได้อย่างน่าเชื่อถือ!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nการทำงานของโปรแกรมเสร็จสิ้น กด Enter เพื่อออก..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nการทำงานของโปรแกรมเสร็จสิ้น กด Enter เพื่อออก...",
|
||||
"Package Mapping & Remediation": "การจับคู่แพ็กเกจและการแก้ไข",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version."
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Açıklama:",
|
||||
"Desktop Application": "Masaüstü Uygulaması",
|
||||
"Detailed Mode": "Ayrıntılı Mod",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Projede birden fazla giriş betiği algılandı. Lütfen derlemek için birini seçin:",
|
||||
"Directory": "Dizin",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Tarayıcıyla keşfedildi ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Disk alanı kritik düzeyde düşük: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Geçerli dizinde requirements.txt dosyasını otomatik aramak için boş bırakın",
|
||||
"Legacy macOS Compatible": "Eski macOS Uyumlu",
|
||||
"Lite Mode (Smaller size)": "Hafif Mod (Daha küçük boyut)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Yüklenen Proje: {name} | Giriş: {entry}",
|
||||
"Loaded: {filename}": "Yüklendi: {filename}",
|
||||
"Locally Detected Pythons": "Yerel Olarak Algılanan Python'lar",
|
||||
"Lock Core Dependencies": "Çekirdek Bağımlılıkları Kilitle",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Betik yüklendi. Varlık klasörlerini veya veri dosyalarını doğrudan buraya sürükleyerek paketleyebilirsiniz.",
|
||||
"Select .pfx / .p12 certificate file": ".pfx / .p12 sertifika dosyası seçin",
|
||||
"Select All": "Tümünü Seç",
|
||||
"Select Main Entry Script": "Ana Giriş Betiğini Seçin",
|
||||
"Select Python Version to Download:": "İndirilecek Python Sürümünü Seçin:",
|
||||
"Select shared directory...": "Paylaşılan dizini seç...",
|
||||
"Self-Signed Certificate (*.pfx)": "Kendi Kendine İmzalı Sertifika (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Kaynak kod sözdizimi hataları içeriyor, derleme iptal edildi:\n - Dosya: {file}\n - Tür: {type}\n - Satır: {line}. satır\n - Ayrıntı: {desc}\n\nİpucu: Paketlemeden önce kaynak kodun yerel olarak çalıştığından emin olun.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Kaynak kod sözdizimi ayrıştırması başarısız oldu, derleme iptal edildi:\n - Dosya: {file}\n - Ayrıntı: {desc}\n\nİpucu: Bu genellikle paketleme aracının hatası değildir.\nSeçtiğiniz [Derleme Python Sürümü]'nün, kodu [Yazarken/Test Ederken] kullandığınız sürümle eşleştiğinden emin olun.\nDaha yeni sözdizimi (ör. walrus operatörü :=, tip birleşimleri |, match-case) daha eski bir Python ortamında kullanılırsa bu hata tetiklenir.\n[Derleme Ayarları] -> [Motor] bölümünden doğru Python sürümüne geçmenizi öneririz.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Kaynak kod sözdizimi ayrıştırılamadı, derleme iptal edildi:\n - Dosya: {file}\n - Satır: {line}. satır\n - Ayrıntı: {desc}\n\nİpucu: Bu genellikle paketleme aracının hatası DEĞİLDİR.\nSeçtiğiniz [Derleme Python Sürümü] ile [Kodu Yazarken/Test Ederken] kullandığınız sürümün eşleştiğinden emin olun.\nDaha yeni sözdizimi (ör. mors operatörü :=, tür birleşimleri |, match-case) kullanmak eski bir Python ortamında bu hatayı tetikler.\n[Derleme Ayarları] -> [Motor] bölümünden doğru Python sürümüne geçmenizi öneririz.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Betik üst modülü '{mod}' içe aktarıyor. Derleme başarısız olursa, tüm proje klasörünü buraya sürüklemeyi deneyin.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] 'multiprocessing' modülü algılandı. Sonsuz işlem döngülerini (fork bombaları) önlemek için 'multiprocessing.freeze_support()' çağrısının 'if __name__ == \"__main__\":' altında yapıldığından emin olun.",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] AST Analiz İstisnası: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Komut zaman aşımı (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Hedef proje bir Bulut Senkronizasyon dizininde (örn. OneDrive/Dropbox). Bulut senkronizasyonu derleme dosyalarını geçici olarak kilitleyebilir.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Zaman damgası sunucusu bağlantısı zaman aşımına uğradı, yerel hızlı imzalama yapılıyor...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] '__file__' kullanımı algılandı. PyInstaller Tek Dosya modunda, paketlenmiş kaynak dosyalarını güvenilir şekilde bulmak için 'sys._MEIPASS' kullanın!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nProgram yürütme tamamlandı, çıkmak için Enter'a basın..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nProgram yürütme tamamlandı, çıkmak için Enter'a basın...",
|
||||
"Package Mapping & Remediation": "Paket Eşleme ve Düzeltme"
|
||||
}
|
||||
@@ -87,6 +87,7 @@
|
||||
"Description:": "Mô tả:",
|
||||
"Desktop Application": "Ứng dụng máy tính để bàn",
|
||||
"Detailed Mode": "Chế độ chi tiết",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "Phát hiện nhiều script khởi chạy trong dự án. Vui lòng chọn một để xây dựng:",
|
||||
"Directory": "Thư mục",
|
||||
"Discovered via scanner ({count}): {pkgs}": "Được phát hiện qua máy quét ({count}): {pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "Dung lượng đĩa cực thấp: {free:.1f}GB < {min:.1f}GB",
|
||||
@@ -148,6 +149,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "Để trống để tự động tìm kiếm requirements.txt trong thư mục hiện tại",
|
||||
"Legacy macOS Compatible": "Tương Thích macOS Cũ",
|
||||
"Lite Mode (Smaller size)": "Chế Độ Gọn Nhẹ (Kích thước nhỏ hơn)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "Đã tải dự án: {name} | Điểm vào: {entry}",
|
||||
"Loaded: {filename}": "Đã tải: {filename}",
|
||||
"Locally Detected Pythons": "Python Được Phát Hiện Cục Bộ",
|
||||
"Lock Core Dependencies": "Khóa Các Phụ Thuộc Cốt Lõi",
|
||||
@@ -250,6 +252,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "Tập lệnh đã được tải. Bạn có thể kéo trực tiếp các thư mục tài sản hoặc tệp dữ liệu vào đây để đóng gói.",
|
||||
"Select .pfx / .p12 certificate file": "Chọn tệp chứng chỉ .pfx / .p12",
|
||||
"Select All": "Chọn tất cả",
|
||||
"Select Main Entry Script": "Chọn Script Khởi Chạy Chính",
|
||||
"Select Python Version to Download:": "Chọn phiên bản Python để tải xuống:",
|
||||
"Select shared directory...": "Chọn thư mục dùng chung...",
|
||||
"Self-Signed Certificate (*.pfx)": "Chứng chỉ tự ký (*.pfx)",
|
||||
@@ -377,6 +380,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] Mã nguồn chứa lỗi cú pháp, biên dịch bị hủy:\n - Tệp: {file}\n - Loại: {type}\n - Dòng: Dòng {line}\n - Chi tiết: {desc}\n\nMẹo: Vui lòng đảm bảo mã nguồn chạy cục bộ trước khi đóng gói.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Phân tích cú pháp mã nguồn thất bại, hủy xây dựng:\n - Tệp: {file}\n - Chi tiết: {desc}\n\nMẹo: Đây thường KHÔNG phải lỗi của công cụ đóng gói.\nVui lòng đảm bảo [Phiên bản Python xây dựng] bạn chọn khớp với phiên bản bạn đã dùng để [Viết/Kiểm tra mã].\nSử dụng cú pháp mới hơn (ví dụ: toán tử walrus :=, union type |, match-case) trong môi trường Python cũ sẽ gây ra lỗi này.\nChúng tôi khuyên bạn nên đến [Cài đặt xây dựng] -> [Công cụ] để chuyển sang phiên bản Python chính xác.",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] Phân tích cú pháp mã nguồn thất bại, xây dựng bị hủy:\n - Tệp: {file}\n - Dòng: Dòng {line}\n - Chi tiết: {desc}\n\nMẹo: Đây thường KHÔNG phải lỗi của công cụ đóng gói.\nVui lòng đảm bảo [Phiên bản Python xây dựng] bạn chọn khớp với phiên bản bạn đã dùng để [Viết/Kiểm tra mã].\nSử dụng cú pháp mới hơn (ví dụ: toán tử hải mã :=, union kiểu |, match-case) trong môi trường Python cũ hơn sẽ gây ra lỗi này.\nChúng tôi khuyên bạn nên đến [Cài đặt xây dựng] -> [Công cụ] để chuyển sang phiên bản Python chính xác.",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] Script nhập mô-đun cha '{mod}'. Nếu xây dựng thất bại, hãy thử kéo toàn bộ thư mục dự án vào đây.",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] Đã phát hiện mô-đun 'multiprocessing'. Đảm bảo gọi 'multiprocessing.freeze_support()' trong 'if __name__ == \"__main__\":' để tránh vòng lặp tiến trình vô hạn (fork bombs).",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] Ngoại lệ phân tích AST: {error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] Hết thời gian chờ lệnh (>{timeout}s)",
|
||||
@@ -405,5 +409,6 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] Dự án mục tiêu nằm trong thư mục Đồng bộ đám mây (ví dụ: OneDrive/Dropbox). Đồng bộ đám mây có thể tạm thời khóa các tệp xây dựng.",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] Kết nối máy chủ dấu thời gian hết thời gian chờ, thực hiện ký nhanh cục bộ...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] Phát hiện việc sử dụng '__file__'. Trong chế độ Một tệp PyInstaller, hãy sử dụng 'sys._MEIPASS' để định vị đáng tin cậy các tệp tài nguyên được đóng gói!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nChương trình đã thực thi xong, nhấn Enter để thoát..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\nChương trình đã thực thi xong, nhấn Enter để thoát...",
|
||||
"Package Mapping & Remediation": "Ánh xạ gói & Khắc phục"
|
||||
}
|
||||
@@ -86,6 +86,7 @@
|
||||
"Description:": "描述::",
|
||||
"Desktop Application": "桌面應用程式",
|
||||
"Detailed Mode": "詳細模式",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "偵測到專案中有多個進入點腳本。請選擇一個來建置::",
|
||||
"Directory": "目錄",
|
||||
"Discovered via scanner ({count}): {pkgs}": "透過掃描器發現({count}):{pkgs}",
|
||||
"Disk space critically low: {free:.1f}GB < {min:.1f}GB": "磁碟空間嚴重不足:{free:.1f}GB < {min:.1f}GB",
|
||||
@@ -147,6 +148,7 @@
|
||||
"Leave blank to auto-search requirements.txt in current directory": "留空以在目前目錄自動搜尋 requirements.txt",
|
||||
"Legacy macOS Compatible": "舊版 macOS 相容",
|
||||
"Lite Mode (Smaller size)": "精簡模式(較小體積)",
|
||||
"Loaded Project: {name} | Entry: {entry}": "已載入專案:{name} | 進入點:{entry}",
|
||||
"Loaded: {filename}": "已載入:{filename}",
|
||||
"Locally Detected Pythons": "本機偵測到的 Python",
|
||||
"Lock Core Dependencies": "鎖定核心依賴項",
|
||||
@@ -249,6 +251,7 @@
|
||||
"Script loaded. You can drag asset folders or data files directly here to bundle them.": "腳本已載入。您可以將資產資料夾或資料檔案直接拖曳到這裡以進行捆綁。",
|
||||
"Select .pfx / .p12 certificate file": "選擇 .pfx / .p12 憑證檔案",
|
||||
"Select All": "全選",
|
||||
"Select Main Entry Script": "選擇主要進入點腳本",
|
||||
"Select Python Version to Download:": "選擇要下載的 Python 版本::",
|
||||
"Select shared directory...": "選擇共用目錄...",
|
||||
"Self-Signed Certificate (*.pfx)": "自簽憑證 (*.pfx)",
|
||||
@@ -375,6 +378,7 @@
|
||||
"[Syntax Error] Source code contains syntax errors, compilation aborted:\n - File: {file}\n - Type: {type}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: Please ensure the source code runs locally before packaging.": "[Syntax Error] 原始碼包含語法錯誤,編譯已中止:\n - 檔案:{file}\n - 類型:{type}\n - 行號:第 {line} 行\n - 詳細資訊:{desc}\n\n提示:請確保原始碼在打包前可於本機正常執行。",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] 原始碼語法解析失敗,建置已中止:\n - 檔案:{file}\n - 詳細資訊:{desc}\n\n提示:這通常不是打包工具的錯誤。\n請確保您選擇的 [建置 Python 版本] 與您用來 [撰寫/測試程式碼] 的版本相符。\n在較舊的 Python 環境中使用較新的語法(例如海象運算子 :=、型別聯集 |、match-case)會觸發此錯誤。\n我們建議前往 [建置設定] -> [引擎] 切換到正確的 Python 版本。",
|
||||
"[Syntax Error] Source code syntax parsing failed, build aborted:\n - File: {file}\n - Line: Line {line}\n - Detail: {desc}\n\nTip: This is usually NOT a fault of the packaging tool.\nPlease ensure the [Build Python Version] you selected matches the version you used to [Write/Test the Code].\nUsing newer syntax (e.g., walrus operator :=, type unions |, match-case) in an older Python environment will trigger this error.\nWe recommend going to [Build Settings] -> [Engine] to switch to the correct Python version.": "[Syntax Error] 原始碼語法剖析失敗,建置已中止:\n - 檔案:{file}\n - 行號:第 {line} 行\n - 詳細資訊:{desc}\n\n提示:這通常不是打包工具的錯誤。\n請確保您選擇的 [建置 Python 版本] 與您 [撰寫/測試程式碼] 時使用的版本相符。\n在較舊的 Python 環境中使用較新的語法(例如海象運算子 :=、型別聯集 |、match-case)會觸發此錯誤。\n我們建議前往 [建置設定] -> [引擎] 切換至正確的 Python 版本。",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[TIP] 腳本匯入了父模組「{mod}」。如果建置失敗,請嘗試將整個專案資料夾拖曳到此處。",
|
||||
"[WARN] 'multiprocessing' module detected. Ensure 'multiprocessing.freeze_support()' is called under 'if __name__ == \"__main__\":' to prevent infinite process loops (fork bombs).": "[WARN] 偵測到 'multiprocessing' 模組。請確保在 'if __name__ == \"__main__\":' 下呼叫 'multiprocessing.freeze_support()',以防止無限程序迴圈(fork 炸彈)。",
|
||||
"[WARN] AST Analysis Exception: {error}": "[WARN] AST 分析例外狀況:{error}",
|
||||
"[WARN] Command timeout (>{timeout}s)": "[WARN] 命令逾時(>{timeout} 秒)",
|
||||
@@ -403,5 +407,8 @@
|
||||
"[WARN] Target project is in a Cloud Sync directory (e.g. OneDrive/Dropbox). Cloud sync may temporarily lock build files.": "[WARN] 目標專案位於雲端同步目錄(例如 OneDrive/Dropbox)。雲端同步可能暫時鎖定建置檔案。",
|
||||
"[WARN] Timestamp server connection timed out, performing local fast signing...": "[WARN] 時間戳伺服器連線逾時,執行本機快速簽章...",
|
||||
"[WARN] Usage of '__file__' detected. In PyInstaller One-File mode, use 'sys._MEIPASS' to reliably locate bundled resource files!": "[WARN] 偵測到 '__file__' 的使用。在 PyInstaller 單一檔案模式中,請使用 'sys._MEIPASS' 以可靠地定位捆綁的資源檔案!",
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\n程式執行完成,按 Enter 鍵退出..."
|
||||
"\\nProgram execution completed, press Enter to exit...": "\\n程式執行完成,按 Enter 鍵退出...",
|
||||
"Cancel": "取消",
|
||||
"Package Mapping & Remediation": "套件對應與修復",
|
||||
"Unknown": "未知"
|
||||
}
|
||||
+270
-69
@@ -125,7 +125,7 @@ except ImportError:
|
||||
HAS_QT_AUDIO = False
|
||||
|
||||
__app_name__ = "QPyPack"
|
||||
__version__ = "2.7.14"
|
||||
__version__ = "2.8.0"
|
||||
__author__ = "QwejayHuang"
|
||||
__company__ = "QwejayHuang"
|
||||
__description__ = "Modern Cross-Platform Python Packaging GUI Powered by PyInstaller & Nuitka"
|
||||
@@ -587,6 +587,10 @@ ZH_CN_DICT = {
|
||||
"Nuitka Compiles source code into native C/C++ binary. Produces smaller package size, faster execution, and deep anti-decompilation protection (requires C compiler).": "Nuitka 将源代码编译为原生C/C++二进制文件。生成包体积更小,执行速度更快,并具有深度反反编译保护(需要C编译器)。",
|
||||
"PyInstaller Bundles Python interpreter and bytecode. Fast build speed, zero configuration (no C compiler needed), and excellent compatibility.": "PyInstaller 打包Python解释器和字节码。构建速度快,零配置(无需C编译器),兼容性极佳。",
|
||||
"Use Custom Commercial Cert (Optional) ": "使用自定义商业证书(可选)",
|
||||
"Select Main Entry Script": "选择项目主入口脚本",
|
||||
"Detected multiple entry scripts in project. Please select one to build:": "在项目目录下检测到多个 Python 脚本,请选择主程序入口:",
|
||||
"Loaded Project: {name} | Entry: {entry}": "已载入项目: {name} | 入口: {entry}",
|
||||
"[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.": "[提示] 脚本引用了上级模块 '{mod}'。如构建报错,可直接将项目总文件夹拖入软件打包。",
|
||||
"Unknown": "未知"
|
||||
}
|
||||
|
||||
@@ -774,27 +778,34 @@ PYPI_MIRRORS_GLOBAL = [
|
||||
]
|
||||
|
||||
DEFAULT_MAPPINGS = {
|
||||
"acoustid": "pyacoustid",
|
||||
"crypto": "pycryptodome",
|
||||
"Crypto": "pycryptodome",
|
||||
"cryptodome": "pycryptodome",
|
||||
"Cryptodome": "pycryptodome",
|
||||
"nacl": "pynacl",
|
||||
"jwt": "PyJWT",
|
||||
"OpenSSL": "pyOpenSSL",
|
||||
|
||||
"cv2": "opencv-python",
|
||||
"PIL": "pillow",
|
||||
"Pillow": "pillow",
|
||||
"skimage": "scikit-image",
|
||||
"vlc": "python-vlc",
|
||||
"pyzbar": "pyzbar",
|
||||
"OpenGL": "PyOpenGL",
|
||||
"pyside6_addons": "PySide6",
|
||||
"pyside6_essentials": "PySide6",
|
||||
"pyside6-addons": "PySide6",
|
||||
"pyside6-essentials": "PySide6",
|
||||
"pyqt5-plugins": "PyQt5",
|
||||
"pyqt5-tools": "PyQt5",
|
||||
"pyqt5_plugins": "PyQt5",
|
||||
"fitz": "pymupdf",
|
||||
"docx": "python-docx",
|
||||
"pptx": "python-pptx",
|
||||
"bs4": "beautifulsoup4",
|
||||
"barcode": "python-barcode",
|
||||
"pdfplumber": "pdfplumber",
|
||||
"barcode": "python-barcode",
|
||||
"soundfile": "soundfile",
|
||||
"mutagen": "mutagen",
|
||||
"vlc": "python-vlc",
|
||||
"pyzbar": "pyzbar",
|
||||
"OpenGL": "PyOpenGL",
|
||||
|
||||
"serial": "pyserial",
|
||||
"usb": "pyusb",
|
||||
"bluetooth": "pybluez",
|
||||
"pynput": "pynput",
|
||||
"magic": "python-magic",
|
||||
"win32com": "pywin32",
|
||||
"win32api": "pywin32",
|
||||
"win32con": "pywin32",
|
||||
@@ -811,33 +822,26 @@ DEFAULT_MAPPINGS = {
|
||||
"win32crypt": "pywin32",
|
||||
"pythoncom": "pywin32",
|
||||
"pywintypes": "pywin32",
|
||||
"serial": "pyserial",
|
||||
"usb": "pyusb",
|
||||
"bluetooth": "pybluez",
|
||||
|
||||
"bs4": "beautifulsoup4",
|
||||
"dns": "dnspython",
|
||||
"websocket": "websocket-client",
|
||||
"paho": "paho-mqtt",
|
||||
"socketio": "python-socketio",
|
||||
"engineio": "python-engineio",
|
||||
"kafka": "kafka-python",
|
||||
"sklearn": "scikit-learn",
|
||||
"yaml": "pyyaml",
|
||||
"dateutil": "python-dateutil",
|
||||
"jwt": "PyJWT",
|
||||
"Crypto": "pycryptodome",
|
||||
"wx": "wxPython",
|
||||
"desktop_notifier": "desktop-notifier",
|
||||
"dotenv": "python-dotenv",
|
||||
"telegram": "python-telegram-bot",
|
||||
"git": "GitPython",
|
||||
"github": "PyGithub",
|
||||
"gitlab": "python-gitlab",
|
||||
"discord": "discord.py",
|
||||
"OpenSSL": "pyOpenSSL",
|
||||
"ldap": "python-ldap",
|
||||
"magic": "python-magic",
|
||||
"slugify": "python-slugify",
|
||||
"snappy": "python-snappy",
|
||||
|
||||
"yaml": "pyyaml",
|
||||
"dateutil": "python-dateutil",
|
||||
"sklearn": "scikit-learn",
|
||||
"wx": "wxPython",
|
||||
"attr": "attrs",
|
||||
"psycopg2": "psycopg2-binary",
|
||||
"pkg_resources": "setuptools",
|
||||
@@ -845,6 +849,9 @@ DEFAULT_MAPPINGS = {
|
||||
"cx_Oracle": "cx-Oracle",
|
||||
"mysql": "mysql-connector-python",
|
||||
"pydantic_core": "pydantic-core",
|
||||
"slugify": "python-slugify",
|
||||
"snappy": "python-snappy",
|
||||
"acoustid": "pyacoustid",
|
||||
}
|
||||
|
||||
DEFAULT_BACKPORT_RULES = {
|
||||
@@ -1180,7 +1187,6 @@ def is_cloud_sync_path(path_obj: Path) -> bool:
|
||||
]
|
||||
return any(kw in path_str for kw in cloud_keywords)
|
||||
|
||||
|
||||
def extract_project_imports_via_ast(target_path, scan_dir: bool = False) -> set:
|
||||
imports = set()
|
||||
target_path = Path(target_path)
|
||||
@@ -1189,9 +1195,9 @@ def extract_project_imports_via_ast(target_path, scan_dir: bool = False) -> set:
|
||||
files_to_scan = [target_path] if target_path.is_file() else []
|
||||
else:
|
||||
files_to_scan = []
|
||||
for root, _, files in os.walk(target_path):
|
||||
for root, _dirs, files in os.walk(target_path):
|
||||
path_parts = set(Path(root).parts)
|
||||
if path_parts & {"__pycache__", ".qpypack_build", ".qpypack_venv", ".venv", "venv", "build", "dist", "env", ".env"}:
|
||||
if path_parts & {"__pycache__", ".qpypack_build", ".qpypack_venv", ".venv", "venv", "build", "dist", "env", ".env", ".git"}:
|
||||
continue
|
||||
for file in files:
|
||||
if file.endswith((".py", ".pyw")):
|
||||
@@ -1200,17 +1206,24 @@ def extract_project_imports_via_ast(target_path, scan_dir: bool = False) -> set:
|
||||
for file_p in files_to_scan:
|
||||
try:
|
||||
code = safe_read_text(file_p)
|
||||
if not code.strip():
|
||||
continue
|
||||
tree = ast.parse(code, filename=file_p.as_posix())
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.Import):
|
||||
imports.update(n.name.split(".")[0] for n in node.names)
|
||||
elif isinstance(node, ast.ImportFrom) and node.level == 0 and node.module:
|
||||
imports.add(node.module.split(".")[0])
|
||||
for n in node.names:
|
||||
top_pkg = n.name.split(".")[0].strip()
|
||||
if top_pkg:
|
||||
imports.add(top_pkg)
|
||||
elif isinstance(node, ast.ImportFrom):
|
||||
if node.level == 0 and node.module:
|
||||
top_pkg = node.module.split(".")[0].strip()
|
||||
if top_pkg:
|
||||
imports.add(top_pkg)
|
||||
except Exception:
|
||||
pass
|
||||
return imports
|
||||
|
||||
|
||||
def query_target_env_packages(python_exe: str) -> dict:
|
||||
if not python_exe or not os.path.exists(python_exe):
|
||||
return {}
|
||||
@@ -1917,6 +1930,69 @@ def get_python_executable():
|
||||
return find_system_python()
|
||||
|
||||
|
||||
def get_all_local_modules(project_root: Path, script_dir: Path) -> set:
|
||||
"""全面扫描项目工作区与脚本目录内的所有本地模块/包名,防止被误判为 PyPI 第三方包去执行 pip install"""
|
||||
local_modules = set()
|
||||
scan_dirs = {project_root, script_dir}
|
||||
if (project_root / "src").exists() and (project_root / "src").is_dir():
|
||||
scan_dirs.add(project_root / "src")
|
||||
|
||||
for s_dir in scan_dirs:
|
||||
try:
|
||||
for p in s_dir.iterdir():
|
||||
if p.name.startswith((".", "__pycache__", "build", "dist", "venv", "env")):
|
||||
continue
|
||||
if p.is_file() and p.suffix.lower() in (".py", ".pyw", ".pyd", ".so"):
|
||||
local_modules.add(p.stem.lower())
|
||||
elif p.is_dir():
|
||||
if (p / "__init__.py").exists() or any(p.glob("*.py")):
|
||||
local_modules.add(p.name.lower())
|
||||
except Exception:
|
||||
pass
|
||||
return local_modules
|
||||
|
||||
|
||||
class EntrySelectDialog(QDialog):
|
||||
"""当用户拖入文件夹且包含多个候选入口脚本时弹出的极简选择框"""
|
||||
def __init__(self, parent, folder_path, py_files):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle(_("Select Main Entry Script"))
|
||||
self.setMinimumWidth(420)
|
||||
self.setStyleSheet("""
|
||||
QDialog { background-color: #ffffff; }
|
||||
QLabel { font-size: 13px; color: #111827; font-weight: bold; }
|
||||
QListWidget { border: 1px solid #d1d5db; border-radius: 6px; padding: 4px; font-family: Consolas, monospace; font-size: 12px; }
|
||||
QListWidget::item { padding: 6px 10px; border-radius: 4px; }
|
||||
QListWidget::item:selected { background-color: #2563eb; color: #ffffff; }
|
||||
QPushButton { background-color: #2563eb; color: #ffffff; border: none; border-radius: 6px; font-size: 12px; font-weight: bold; padding: 6px 16px; min-width: 70px; }
|
||||
QPushButton:hover { background-color: #1d4ed8; }
|
||||
""")
|
||||
lay = QVBoxLayout(self)
|
||||
lay.setSpacing(10)
|
||||
lay.setContentsMargins(20, 20, 20, 20)
|
||||
|
||||
lay.addWidget(QLabel(_("Detected multiple entry scripts in project. Please select one to build:")))
|
||||
self.list_widget = QListWidget()
|
||||
for f in py_files:
|
||||
rel = f.relative_to(folder_path).as_posix()
|
||||
item = QListWidgetItem(f"📄 {rel}")
|
||||
item.setData(Qt.ItemDataRole.UserRole, f.as_posix())
|
||||
self.list_widget.addItem(item)
|
||||
self.list_widget.setCurrentRow(0)
|
||||
lay.addWidget(self.list_widget)
|
||||
|
||||
btn_lay = QHBoxLayout()
|
||||
btn_lay.addStretch()
|
||||
btn_ok = QPushButton(_("OK"))
|
||||
btn_ok.clicked.connect(self.accept)
|
||||
btn_lay.addWidget(btn_ok)
|
||||
lay.addLayout(btn_lay)
|
||||
|
||||
def get_selected_script(self):
|
||||
item = self.list_widget.currentItem()
|
||||
return item.data(Qt.ItemDataRole.UserRole) if item else None
|
||||
|
||||
|
||||
def safe_read_text(path: Path) -> str:
|
||||
try:
|
||||
raw = path.read_bytes()
|
||||
@@ -2383,12 +2459,20 @@ class DropArea(QFrame):
|
||||
if not paths:
|
||||
return
|
||||
|
||||
py_files = [p for p in paths if p.lower().endswith((".py", ".pyw"))]
|
||||
parent_win = self.window()
|
||||
|
||||
# 1. 优先判断是否直接拖入了项目主文件夹
|
||||
first_path = Path(paths[0])
|
||||
if len(paths) == 1 and first_path.is_dir():
|
||||
if hasattr(parent_win, "on_project_folder_selected"):
|
||||
parent_win.on_project_folder_selected(first_path)
|
||||
return
|
||||
|
||||
# 2. 如果拖入的是单脚本文件
|
||||
py_files = [p for p in paths if p.lower().endswith((".py", ".pyw"))]
|
||||
if py_files:
|
||||
self.fileDropped.emit(py_files[0])
|
||||
else:
|
||||
parent_win = self.window()
|
||||
if hasattr(parent_win, "on_main_resources_dropped"):
|
||||
parent_win.on_main_resources_dropped(paths)
|
||||
|
||||
@@ -4961,6 +5045,10 @@ class PackingThread(QThread):
|
||||
if extra_env:
|
||||
clean_env.update(extra_env)
|
||||
|
||||
proj_folder = self.params.get("project_folder")
|
||||
if proj_folder and os.path.exists(proj_folder):
|
||||
clean_env["PYTHONPATH"] = proj_folder + (os.pathsep + clean_env["PYTHONPATH"] if "PYTHONPATH" in clean_env else "")
|
||||
|
||||
try:
|
||||
kwargs = {
|
||||
"stdout": subprocess.PIPE,
|
||||
@@ -5115,12 +5203,31 @@ class PackingThread(QThread):
|
||||
"# -------------------------------------------\n\n"
|
||||
)
|
||||
|
||||
try:
|
||||
tree = ast.parse(code, filename=orig_path.as_posix())
|
||||
last_future_lineno = 0
|
||||
for node in tree.body:
|
||||
if isinstance(node, ast.ImportFrom) and node.module == "__future__":
|
||||
last_future_lineno = max(last_future_lineno, getattr(node, "end_lineno", node.lineno))
|
||||
elif isinstance(node, ast.Expr) and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):
|
||||
last_future_lineno = max(last_future_lineno, getattr(node, "end_lineno", node.lineno))
|
||||
else:
|
||||
break
|
||||
|
||||
lines = code.splitlines(keepends=True)
|
||||
if last_future_lineno > 0:
|
||||
injected_code = "".join(lines[:last_future_lineno]) + "\n" + pause_code + "".join(lines[last_future_lineno:])
|
||||
else:
|
||||
injected_code = pause_code + code
|
||||
except Exception:
|
||||
injected_code = pause_code + code
|
||||
|
||||
temp_file = orig_path.parent / f"_qpypack_temp_{orig_path.name}"
|
||||
try:
|
||||
temp_file.write_text(pause_code + code, encoding="utf-8")
|
||||
temp_file.write_text(injected_code, encoding="utf-8")
|
||||
except PermissionError:
|
||||
temp_file = Path(tempfile.gettempdir()) / f"_qpypack_temp_{orig_path.name}"
|
||||
temp_file.write_text(pause_code + code, encoding="utf-8")
|
||||
temp_file.write_text(injected_code, encoding="utf-8")
|
||||
os.environ["PYTHONPATH"] = orig_path.parent.as_posix() + os.pathsep + os.environ.get("PYTHONPATH", "")
|
||||
|
||||
return temp_file, True, ""
|
||||
@@ -5502,19 +5609,20 @@ class PackingThread(QThread):
|
||||
pass
|
||||
|
||||
def parse_req_line(line):
|
||||
line = line.strip()
|
||||
if not line or line.startswith(("#", "-")):
|
||||
line = line.split("#")[0].strip()
|
||||
if not line or line.startswith(("-", "@")):
|
||||
return None, None
|
||||
m = re.match(r"^([a-zA-Z0-9_\-\.]+)(.*)$", line)
|
||||
line_no_marker = line.split(";")[0].strip()
|
||||
m = re.match(r"^([a-zA-Z0-9_\-\.]+)(.*)$", line_no_marker)
|
||||
if m:
|
||||
pkg_raw = m.group(1)
|
||||
pkg_raw = m.group(1).strip()
|
||||
canon_name = get_canonical_pypi_name(pkg_raw)
|
||||
if canon_name.lower() in target_std_libs:
|
||||
return None, None
|
||||
if canon_name.lower() != pkg_raw.lower():
|
||||
full_spec = canon_name
|
||||
full_spec = canon_name + m.group(2).strip()
|
||||
else:
|
||||
full_spec = line
|
||||
full_spec = line_no_marker
|
||||
return canon_name, full_spec
|
||||
return None, None
|
||||
|
||||
@@ -5541,11 +5649,12 @@ class PackingThread(QThread):
|
||||
except Exception as e:
|
||||
self.progress.emit(_("[WARN] Read requirements.txt warning: {error}", error=str(e)))
|
||||
|
||||
local_modules = {
|
||||
p.stem.lower()
|
||||
for p in script_dir.iterdir()
|
||||
if (p.is_file() and p.suffix.lower() in (".py", ".pyw", ".pyd", ".so")) or (p.is_dir() and (p / "__init__.py").exists())
|
||||
}
|
||||
proj_folder = self.params.get("project_folder")
|
||||
project_root = Path(proj_folder).resolve() if (proj_folder and Path(proj_folder).exists()) else script_dir
|
||||
|
||||
local_modules = get_all_local_modules(project_root, script_dir)
|
||||
user_added_dirs = {Path(dst).parts[0].lower() for _r_type, src, dst in (self.params.get("add_data_list") or [])}
|
||||
local_modules.update(user_added_dirs)
|
||||
|
||||
for m in script_imports:
|
||||
if m.lower() in target_std_libs or m.lower() in local_modules:
|
||||
@@ -5697,19 +5806,17 @@ class PackingThread(QThread):
|
||||
|
||||
self.progress.emit(_("[INFO] Scanning project source code via AST engine..."))
|
||||
|
||||
scan_dir_mode = self.params.get("use_pipreqs_dir", False)
|
||||
if scan_dir_mode:
|
||||
ast_discovered_imports = extract_project_imports_via_ast(script_dir, scan_dir=True)
|
||||
else:
|
||||
ast_discovered_imports = script_imports
|
||||
scan_target = project_root if (project_root and project_root.exists()) else script_dir
|
||||
ast_discovered_imports = extract_project_imports_via_ast(scan_target, scan_dir=True)
|
||||
|
||||
env_pkg_map = query_target_env_packages(system_python_exe)
|
||||
|
||||
for m in ast_discovered_imports:
|
||||
if m.lower() in target_std_libs or m.lower() in local_modules:
|
||||
m_lower = m.lower()
|
||||
if m_lower in target_std_libs or m_lower in local_modules:
|
||||
continue
|
||||
canon_name = (env_pkg_map.get(m) or get_canonical_pypi_name(m)).lower()
|
||||
if canon_name not in target_std_libs:
|
||||
canon_name = (env_pkg_map.get(m) or env_pkg_map.get(m_lower) or get_canonical_pypi_name(m)).lower()
|
||||
if canon_name not in target_std_libs and canon_name not in local_modules:
|
||||
auto_detected_pkgs.add(canon_name)
|
||||
if canon_name not in final_dependencies:
|
||||
final_dependencies[canon_name] = canon_name
|
||||
@@ -5972,6 +6079,12 @@ class PackingThread(QThread):
|
||||
f"--name={app_name}",
|
||||
]
|
||||
|
||||
cmd.append(f"--paths={project_root.as_posix()}")
|
||||
if project_root != script_dir:
|
||||
cmd.append(f"--paths={script_dir.as_posix()}")
|
||||
if (project_root / "src").exists():
|
||||
cmd.append(f"--paths={(project_root / 'src').as_posix()}")
|
||||
|
||||
if self.params["onefile"]:
|
||||
cmd.append("--onefile")
|
||||
else:
|
||||
@@ -6054,28 +6167,43 @@ class PackingThread(QThread):
|
||||
hidden_list = [i.strip().lower() for i in (self.params.get("hidden_imports") or "").split(",") if i.strip()]
|
||||
all_imports_lower = imports_lower | set(hidden_list)
|
||||
|
||||
if any(k in all_imports_lower for k in ("crypto", "pycryptodome", "cryptography", "nacl", "pynacl")):
|
||||
cmd.extend(["--collect-all", "Crypto"])
|
||||
cmd.extend(["--collect-all", "pycryptodome"])
|
||||
cmd.extend(["--collect-all", "cryptography"])
|
||||
cmd.extend(["--collect-all", "nacl"])
|
||||
|
||||
if "pynput" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "pynput"])
|
||||
if "keyring" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "keyring"])
|
||||
if "soundfile" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "soundfile"])
|
||||
|
||||
if "ttkbootstrap" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "ttkbootstrap"])
|
||||
if "customtkinter" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "customtkinter"])
|
||||
if "gradio" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "gradio"])
|
||||
if "matplotlib" in all_imports_lower or "seaborn" in all_imports_lower:
|
||||
cmd.extend(["--collect-data", "matplotlib"])
|
||||
|
||||
if "playwright" in all_imports_lower or has_playwright_pkg:
|
||||
cmd.extend(["--collect-all", "playwright"])
|
||||
if "moviepy" in all_imports_lower:
|
||||
cmd.extend(["--collect-data", "moviepy"])
|
||||
if "gradio" in all_imports_lower:
|
||||
cmd.extend(["--collect-all", "gradio"])
|
||||
|
||||
if "pydantic" in all_imports_lower:
|
||||
cmd.extend(["--collect-submodules", "pydantic"])
|
||||
if "matplotlib" in all_imports_lower or "seaborn" in all_imports_lower:
|
||||
cmd.extend(["--collect-data", "matplotlib"])
|
||||
|
||||
if any(lib in all_imports_lower for lib in ("requests", "httpx", "urllib3", "aiohttp")):
|
||||
cmd.extend(["--collect-submodules", "pydantic_core"])
|
||||
if any(lib in all_imports_lower for lib in ("requests", "httpx", "urllib3", "aiohttp", "urllib")):
|
||||
cmd.extend(["--collect-data", "certifi"])
|
||||
self.progress.emit(
|
||||
_("[WARN] Detected 'requests' or 'httpx'. Auto-bundling 'certifi' certificates to prevent SSL errors.")
|
||||
)
|
||||
|
||||
for web_fw in ("fastapi", "uvicorn", "flask", "streamlit", "pywebio", "dash", "pyecharts", "pyppeteer"):
|
||||
for web_fw in ("fastapi", "uvicorn", "flask", "starlette", "sqlalchemy", "tortoise", "streamlit", "pywebio", "dash", "pyecharts", "pyppeteer"):
|
||||
if web_fw in all_imports_lower:
|
||||
cmd.extend(["--collect-all", web_fw])
|
||||
|
||||
@@ -6091,6 +6219,10 @@ class PackingThread(QThread):
|
||||
f"--output-filename={app_name}{ext}",
|
||||
]
|
||||
|
||||
for mod_name in local_modules:
|
||||
if (project_root / mod_name).is_dir():
|
||||
cmd.append(f"--include-package={mod_name}")
|
||||
|
||||
base_nuitka_excludes = ["unittest", "doctest", "pdb", "pydoc", "test", "pytest", "IPython", "setuptools"]
|
||||
for ex in base_nuitka_excludes:
|
||||
cmd.append(f"--nofollow-import-to={ex}")
|
||||
@@ -6325,13 +6457,21 @@ class PackingThread(QThread):
|
||||
cmd.append("--include-package=playwright")
|
||||
cmd.append("--include-package-data=playwright")
|
||||
|
||||
if any(lib in imports_lower for lib in ("requests", "httpx", "urllib3", "aiohttp")):
|
||||
if any(k in imports_lower for k in ("crypto", "pycryptodome", "cryptography", "nacl", "pynacl")):
|
||||
cmd.append("--include-package=Crypto")
|
||||
cmd.append("--include-package=cryptography")
|
||||
if "pynput" in imports_lower:
|
||||
cmd.append("--include-package=pynput")
|
||||
if "soundfile" in imports_lower:
|
||||
cmd.append("--include-package=soundfile")
|
||||
|
||||
if any(lib in imports_lower for lib in ("requests", "httpx", "urllib3", "aiohttp", "urllib")):
|
||||
cmd.append("--include-package-data=certifi")
|
||||
self.progress.emit(
|
||||
_("[WARN] Detected 'requests' or 'httpx'. Auto-bundling 'certifi' certificates to prevent SSL errors.")
|
||||
)
|
||||
|
||||
for web_fw in ("fastapi", "uvicorn", "flask", "streamlit", "pywebio", "dash", "pyecharts", "pyppeteer"):
|
||||
for web_fw in ("fastapi", "uvicorn", "flask", "starlette", "sqlalchemy", "tortoise", "streamlit", "pywebio", "dash", "pyecharts", "pyppeteer"):
|
||||
if web_fw in imports_lower:
|
||||
if not is_lite:
|
||||
cmd.append(f"--include-package={web_fw}")
|
||||
@@ -6358,7 +6498,7 @@ class PackingThread(QThread):
|
||||
|
||||
for excl in (self.params.get("exclude_modules") or "").split(","):
|
||||
if excl.strip():
|
||||
cmd.append(f"--nofollow-import-to={excl.strip()}")
|
||||
cmd.extend(["--nofollow-import-to={excl.strip()}"])
|
||||
|
||||
if self.params.get("lite_mode"):
|
||||
self.progress.emit(_("[INFO] Lite mode enabled, applying bytecode optimization (-OO) and stripping dev modules..."))
|
||||
@@ -6972,6 +7112,7 @@ class MainWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.script_path = ""
|
||||
self.project_folder = None
|
||||
self.thread = None
|
||||
self.analysis_thread = None
|
||||
self.current_state = "idle"
|
||||
@@ -7492,12 +7633,58 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
self.show_notification(_("[INFO] Added {count} resource item(s) to Additional Resources.", count=count))
|
||||
|
||||
def on_project_folder_selected(self, folder_path: Path):
|
||||
folder_path = folder_path.resolve()
|
||||
candidates = []
|
||||
for root, _dirs, files in os.walk(folder_path):
|
||||
parts = set(Path(root).parts)
|
||||
if parts & {"__pycache__", ".git", ".venv", "venv", "build", "dist", ".qpypack_build", ".qpypack_venv"}:
|
||||
continue
|
||||
for f in files:
|
||||
if f.endswith((".py", ".pyw")):
|
||||
candidates.append(Path(root) / f)
|
||||
|
||||
if not candidates:
|
||||
self.show_error_log(_("[ERROR] Please load a valid Python source file first!"))
|
||||
return
|
||||
|
||||
priority_names = ["main.py", "app.py", "server.py", "run.py", "start.py", "unlocker.py", "gui.py", "cli.py"]
|
||||
selected_script = None
|
||||
|
||||
for p_name in priority_names:
|
||||
matched = [c for c in candidates if c.name.lower() == p_name]
|
||||
if matched:
|
||||
selected_script = matched[0].as_posix()
|
||||
break
|
||||
|
||||
if not selected_script:
|
||||
if len(candidates) == 1:
|
||||
selected_script = candidates[0].as_posix()
|
||||
else:
|
||||
dlg = EntrySelectDialog(self, folder_path, candidates)
|
||||
if dlg.exec() == QDialog.DialogCode.Accepted:
|
||||
selected_script = dlg.get_selected_script()
|
||||
else:
|
||||
return
|
||||
|
||||
if selected_script:
|
||||
self.project_folder = folder_path.as_posix()
|
||||
root_reqs = folder_path / "requirements.txt"
|
||||
if root_reqs.exists():
|
||||
self.settings_panel.reqs_file_edit.setText(root_reqs.as_posix())
|
||||
|
||||
self.on_script_selected(selected_script)
|
||||
self.show_notification(_("Loaded Project: {name} | Entry: {entry}", name=folder_path.name, entry=Path(selected_script).name), 6000)
|
||||
|
||||
def on_script_selected(self, path):
|
||||
path = Path(path).resolve().as_posix()
|
||||
if is_cloud_locked(path):
|
||||
self.show_error_log(_("[ERROR] Target file is locked or encrypted by cloud drive. Please decrypt and try again."))
|
||||
return
|
||||
|
||||
if not getattr(self, "project_folder", None) or Path(self.project_folder) not in Path(path).parents:
|
||||
self.project_folder = None
|
||||
|
||||
if self.script_path != path:
|
||||
self.settings_panel.icon_edit.clear()
|
||||
self.settings_panel.hidden_edit.clear()
|
||||
@@ -7633,6 +7820,18 @@ class MainWindow(QMainWindow):
|
||||
self.log_concise.clear()
|
||||
self.log_detailed.clear()
|
||||
self.append_log(_("Loaded: {filename}", filename=path))
|
||||
|
||||
if not self.project_folder:
|
||||
script_path_obj = Path(path).resolve()
|
||||
parent_dir = script_path_obj.parent.parent
|
||||
if parent_dir and parent_dir != script_path_obj.parent:
|
||||
for imp in script_imports:
|
||||
top_m = imp.split(".")[0]
|
||||
if (parent_dir / top_m).exists() or (parent_dir / f"{top_m}.py").exists():
|
||||
tip_text = _("[TIP] Script imports parent module '{mod}'. If build fails, try dragging the whole project folder here.", mod=top_m)
|
||||
self.append_log(tip_text)
|
||||
break
|
||||
|
||||
self.show_notification(_("Script loaded. You can drag asset folders or data files directly here to bundle them."), 6000)
|
||||
self.btn_main.setEnabled(True)
|
||||
self.update_ui_state("ready")
|
||||
@@ -7823,6 +8022,7 @@ class MainWindow(QMainWindow):
|
||||
"engine": engine,
|
||||
"python_exe": raw_py,
|
||||
"script_path": self.script_path,
|
||||
"project_folder": self.project_folder,
|
||||
"enable_sign": sp.enable_sign_check.isChecked(),
|
||||
"cert_path": sp.cert_path_edit.text().strip(),
|
||||
"cert_pass": sp.cert_pass_edit.text().strip(),
|
||||
@@ -7966,6 +8166,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def reset_all(self):
|
||||
self.script_path = ""
|
||||
self.project_folder = None
|
||||
self.settings_panel.name_edit.clear()
|
||||
self.settings_panel.icon_edit.clear()
|
||||
self.settings_panel.hidden_edit.clear()
|
||||
@@ -8253,4 +8454,4 @@ def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
@@ -0,0 +1,546 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
=============================================================================
|
||||
QPyPack 全功能终极一体化自检与双引擎真实打包验证系统 (UI 深度集成完整版)
|
||||
=============================================================================
|
||||
特性:
|
||||
- 深度集成:直接实例化 MainWindow 模拟用户拖拽与点击,完整测试 UI->Engine 链路
|
||||
- 前瞻兼容:不写死参数字典,直接读取 UI 界面控件生成的配置,随软件升级自动适配
|
||||
- 自动自净:测试开始前与结束后自动抹除一切 build/、spec、egg-info 残留
|
||||
- 全量覆盖:包含 AST 分析、I18N 多语言引擎、状态机逻辑等 8 大核心维度
|
||||
=============================================================================
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import time
|
||||
import shutil
|
||||
import zipfile
|
||||
import tempfile
|
||||
import subprocess
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
|
||||
# 全局开启 Qt 无头模式与 Windows 字体 (屏蔽无关警告)
|
||||
os.environ["QT_QPA_PLATFORM"] = "offscreen"
|
||||
if sys.platform == "win32":
|
||||
os.environ["PYTHONIOENCODING"] = "utf-8"
|
||||
if os.path.exists(r"C:\Windows\Fonts"):
|
||||
os.environ["QT_QPA_FONTDIR"] = r"C:\Windows\Fonts"
|
||||
os.environ["QT_LOGGING_RULES"] = "qt.qpa.fonts=false;qt.qpa.*=false;qt.multimedia*=false"
|
||||
|
||||
current_path = Path(__file__).resolve()
|
||||
if current_path.parent.name == "tests":
|
||||
ROOT_DIR = current_path.parent.parent
|
||||
else:
|
||||
ROOT_DIR = current_path.parent
|
||||
|
||||
PACKAGE_DIR = ROOT_DIR / "qpypack"
|
||||
LOCALES_DIR = PACKAGE_DIR / "locales"
|
||||
ICON_PATH = PACKAGE_DIR / "icon.ico"
|
||||
|
||||
if str(ROOT_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT_DIR))
|
||||
|
||||
|
||||
class Colors:
|
||||
CYAN = "\033[96m"
|
||||
GREEN = "\033[92m"
|
||||
YELLOW = "\033[93m"
|
||||
RED = "\033[91m"
|
||||
RESET = "\033[0m"
|
||||
BOLD = "\033[1m"
|
||||
|
||||
|
||||
def log_pass(msg):
|
||||
print(f" {Colors.GREEN}✔ [PASS]{Colors.RESET} {msg}")
|
||||
|
||||
|
||||
def log_warn(msg):
|
||||
print(f" {Colors.YELLOW}⚠ [WARN]{Colors.RESET} {msg}")
|
||||
|
||||
|
||||
def log_fail(msg):
|
||||
print(f" {Colors.RED}✖ [FAIL]{Colors.RESET} {msg}")
|
||||
|
||||
|
||||
def log_info(msg):
|
||||
print(f" {Colors.CYAN}ℹ [INFO]{Colors.RESET} {msg}")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 垃圾自净机制 (自动清理根目录残留)
|
||||
# =====================================================================
|
||||
def clean_project_junk():
|
||||
"""扫描并强制清除项目根目录下的所有测试与构建残留"""
|
||||
junk_patterns_dir = ["build", "dist", "*.egg-info", "__pycache__", ".pytest_cache"]
|
||||
junk_patterns_file = ["*.spec", ".coverage"]
|
||||
|
||||
# 清理目录
|
||||
for pattern in junk_patterns_dir:
|
||||
for p in ROOT_DIR.glob(pattern):
|
||||
if p.is_dir() and p != PACKAGE_DIR:
|
||||
try:
|
||||
shutil.rmtree(p, ignore_errors=True)
|
||||
except Exception:
|
||||
pass
|
||||
for p in (ROOT_DIR / "tests").glob(pattern):
|
||||
if p.is_dir():
|
||||
try:
|
||||
shutil.rmtree(p, ignore_errors=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 清理文件
|
||||
for pattern in junk_patterns_file:
|
||||
for p in ROOT_DIR.glob(pattern):
|
||||
if p.is_file():
|
||||
try:
|
||||
p.unlink(missing_ok=True)
|
||||
except Exception:
|
||||
pass
|
||||
for p in (ROOT_DIR / "tests").glob(pattern):
|
||||
if p.is_file():
|
||||
try:
|
||||
p.unlink(missing_ok=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# 测试前先自净一次历史垃圾
|
||||
clean_project_junk()
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 1. 静态资源与配置深度检测
|
||||
# =====================================================================
|
||||
def test_01_static_assets():
|
||||
"""测试 1: 静态资源与配置物理合法性"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 1/8] 静态资源与工程配置完整性检查...{Colors.RESET}")
|
||||
|
||||
assert ICON_PATH.exists(), f"关键图标缺失: {ICON_PATH}"
|
||||
assert ICON_PATH.stat().st_size > 1024, "icon.ico 文件大小异常"
|
||||
with open(ICON_PATH, "rb") as f:
|
||||
header = f.read(4)
|
||||
assert header == b"\x00\x00\x01\x00", "icon.ico 不是有效的 Windows ICO 格式"
|
||||
log_pass(f"图标格式与二进制签名正常 (大小: {ICON_PATH.stat().st_size} bytes)")
|
||||
|
||||
toml_path = ROOT_DIR / "pyproject.toml"
|
||||
assert toml_path.exists(), "pyproject.toml 缺失"
|
||||
assert "qpypack" in toml_path.read_text(encoding="utf-8").lower()
|
||||
log_pass("pyproject.toml 配置文件解析正常")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 2. 16 种多语言语法、Key 一致性与占位符检测
|
||||
# =====================================================================
|
||||
def test_02_locales_and_placeholders():
|
||||
"""测试 2: 16 国多语言深度校验"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 2/8] 16 国国际化语言包与语法占位符检测...{Colors.RESET}")
|
||||
|
||||
assert LOCALES_DIR.is_dir(), "locales 目录不存在"
|
||||
json_files = list(LOCALES_DIR.glob("*.json"))
|
||||
assert len(json_files) == 16, f"应包含 16 种语言包,实际发现 {len(json_files)} 个"
|
||||
log_pass(f"成功定位到全部 {len(json_files)} 个语言包文件")
|
||||
|
||||
parsed = {}
|
||||
for jf in json_files:
|
||||
with open(jf, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
assert isinstance(data, dict), f"{jf.name} 格式非合法字典"
|
||||
parsed[jf.name] = data
|
||||
log_pass("所有语言包 JSON 语法解析正常")
|
||||
|
||||
base_data = parsed.get("zh_CN.json", {})
|
||||
assert base_data, "基准语言包 zh_CN.json 缺失或为空"
|
||||
base_keys = set(base_data.keys())
|
||||
|
||||
missing_map = {}
|
||||
for name, data in parsed.items():
|
||||
if name == "zh_CN.json":
|
||||
continue
|
||||
missing = base_keys - set(data.keys())
|
||||
if missing:
|
||||
missing_map[name] = missing
|
||||
|
||||
if missing_map:
|
||||
for fname, keys in missing_map.items():
|
||||
log_warn(f"{fname} 缺少 {len(keys)} 个词条: {list(keys)[:3]}...")
|
||||
else:
|
||||
log_pass("16 国语言包与 zh_CN.json 词条保持 100% 完全对齐!")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 3. AST 语法分析与依赖提取算法测试
|
||||
# =====================================================================
|
||||
def test_03_ast_engine():
|
||||
"""测试 3: AST 源码静态语法分析与依赖侦测 (QPyPack 原生算法)"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 3/8] AST 静态分析与依赖侦测 (QPyPack 原生算法)...{Colors.RESET}")
|
||||
|
||||
from qpypack.main import extract_project_imports_via_ast
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
mock_file = Path(tmpdir) / "test_ast.py"
|
||||
mock_file.write_text("import os, sys\nimport requests.auth\nfrom PyQt5.QtWidgets import QMainWindow", encoding="utf-8")
|
||||
|
||||
modules = extract_project_imports_via_ast(mock_file, scan_dir=False)
|
||||
assert {"requests", "PyQt5", "os", "sys"}.issubset(modules), f"QPyPack 原生提取异常: {modules}"
|
||||
log_pass(f"QPyPack AST 引擎成功提取模块依赖: {modules}")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 4. 核心模块与入口健全性 (集成配置存储及多语言引擎联调)
|
||||
# =====================================================================
|
||||
def test_04_core_logic():
|
||||
"""测试 4: 核心配置管理与翻译引擎联调测试"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 4/8] QPyPack 核心配置读取与多语言翻译引擎测试...{Colors.RESET}")
|
||||
|
||||
from qpypack.main import load_config, I18N
|
||||
|
||||
config = load_config(retry=True)
|
||||
assert "Settings" in config, "配置生成或加载失败"
|
||||
assert "Mappings" in config, "包名映射字典缺失"
|
||||
|
||||
# 动态切换并断言多语言系统
|
||||
I18N.set_language("en_US")
|
||||
assert I18N.t("Build Settings") == "Build Settings", "英文翻译错误"
|
||||
I18N.set_language("zh_CN")
|
||||
assert I18N.t("Build Settings") == "构建设置", "中文翻译未命中映射"
|
||||
|
||||
log_pass("配置 I/O 系统与 I18N 多语言引擎运行正常")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 5. UI 控件与主窗口状态机独立交互测试
|
||||
# =====================================================================
|
||||
def test_05_ui_interaction():
|
||||
"""测试 5: Qt UI 界面与控件状态机逻辑交互测试 (独立无打包)"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 5/8] Qt UI 控件与状态机模拟交互测试...{Colors.RESET}")
|
||||
|
||||
try:
|
||||
from PySide6.QtWidgets import QApplication
|
||||
app = QApplication.instance() or QApplication(["qp_test", "-platform", "offscreen"])
|
||||
except ImportError:
|
||||
log_warn("未安装 PySide6,跳过 GUI 交互测试")
|
||||
return
|
||||
|
||||
from PySide6.QtCore import QEventLoop, QTimer
|
||||
from qpypack.main import MainWindow
|
||||
window = MainWindow()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
mock_py = Path(tmp_dir) / "mock_app.py"
|
||||
mock_py.write_text("print('hello')", encoding="utf-8")
|
||||
|
||||
# 测试拖入脚本
|
||||
window.on_script_selected(str(mock_py))
|
||||
|
||||
# 等待后台 AST 解析子线程完成
|
||||
loop = QEventLoop()
|
||||
timer = QTimer()
|
||||
timer.timeout.connect(loop.quit)
|
||||
timer.start(1000)
|
||||
loop.exec()
|
||||
timer.stop()
|
||||
|
||||
assert window.current_state == "ready", "脚本载入后状态机未变为 ready"
|
||||
assert window.settings_panel.name_edit.text() == "mock_app", "未成功解析推导出默认程序名"
|
||||
|
||||
# 测试修改引擎配置
|
||||
window.settings_panel.engine_combo.setCurrentIndex(1)
|
||||
assert window.settings_panel.engine_combo.currentText() == "Nuitka"
|
||||
|
||||
log_pass("主窗口完成内存初始化,状态机推导与 UI 数据绑定响应正常")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 6. Wheel 分发包真实打包与解压内嵌资产验证 (沙箱环境零残留)
|
||||
# =====================================================================
|
||||
def test_06_wheel_packaging():
|
||||
"""测试 6: Wheel 包构建与资源嵌入"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 6/8] Wheel (.whl) 分发包构建与资源嵌入深度检查...{Colors.RESET}")
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix="qp_whl_") as tmp_dist:
|
||||
try:
|
||||
build_cmd = [sys.executable, "-m", "build", "--wheel", "--outdir", tmp_dist, str(ROOT_DIR)]
|
||||
result = subprocess.run(build_cmd, capture_output=True, text=True, cwd=tmp_dist)
|
||||
|
||||
if result.returncode != 0:
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-m", "pip", "wheel", "--no-deps", "-w", tmp_dist, str(ROOT_DIR)],
|
||||
capture_output=True, text=True, cwd=tmp_dist
|
||||
)
|
||||
assert result.returncode == 0, f"构建 Wheel 失败:\n{result.stderr}"
|
||||
|
||||
wheels = list(Path(tmp_dist).glob("*.whl"))
|
||||
assert wheels, "未找到生成的 .whl 文件"
|
||||
wheel_file = wheels[0]
|
||||
log_pass(f"成功构建 Wheel: {wheel_file.name}")
|
||||
|
||||
with zipfile.ZipFile(wheel_file, "r") as zf:
|
||||
names = zf.namelist()
|
||||
assert any("icon.ico" in n for n in names), "icon.ico 漏打包进 Wheel!"
|
||||
json_in_wheel = [n for n in names if "locales/" in n and n.endswith(".json")]
|
||||
assert len(json_in_wheel) >= 16, f"语言包未全部嵌入 Wheel (仅 {len(json_in_wheel)} 个)!"
|
||||
log_pass(f"icon.ico 及 16 个语言包已 100% 嵌入 Wheel 压缩包中")
|
||||
finally:
|
||||
clean_project_junk()
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 辅助函数: 创建微型真实测试工程 & 产物实机拉起断言
|
||||
# =====================================================================
|
||||
def _create_mock_project(base_dir: Path) -> Path:
|
||||
proj_dir = base_dir / "mock_app"
|
||||
proj_dir.mkdir(parents=True, exist_ok=True)
|
||||
assets_dir = proj_dir / "assets"
|
||||
assets_dir.mkdir(exist_ok=True)
|
||||
|
||||
with open(assets_dir / "data.json", "w", encoding="utf-8") as f:
|
||||
json.dump({"engine_test": "QPYPACK_REAL_OK"}, f)
|
||||
|
||||
with open(proj_dir / "calc.py", "w", encoding="utf-8") as f:
|
||||
f.write("def multiply(a, b): return a * b\n")
|
||||
|
||||
entry_file = proj_dir / "app_main.py"
|
||||
with open(entry_file, "w", encoding="utf-8") as f:
|
||||
f.write('''# -*- coding: utf-8 -*-
|
||||
__version__ = "1.0.0"
|
||||
__app_name__ = "MockTestApp"
|
||||
|
||||
import sys, os, json, multiprocessing
|
||||
from calc import multiply
|
||||
|
||||
def get_res(rel):
|
||||
if hasattr(sys, '_MEIPASS'):
|
||||
return os.path.join(sys._MEIPASS, rel)
|
||||
return os.path.join(os.path.dirname(os.path.abspath(__file__)), rel)
|
||||
|
||||
if __name__ == '__main__':
|
||||
multiprocessing.freeze_support()
|
||||
calc_res = multiply(6, 7)
|
||||
res_path = get_res(os.path.join("assets", "data.json"))
|
||||
val = "FAIL"
|
||||
if os.path.exists(res_path):
|
||||
with open(res_path, "r", encoding="utf-8") as f:
|
||||
val = json.load(f).get("engine_test", "CORRUPTED")
|
||||
else:
|
||||
val = f"NOT_FOUND:{res_path}"
|
||||
print(f"__QP_ASSERT__|{calc_res}|{val}|__QP_ASSERT_END__")
|
||||
sys.exit(0)
|
||||
''')
|
||||
return entry_file
|
||||
|
||||
|
||||
def _get_size(path: Path):
|
||||
if path.is_file():
|
||||
return path.stat().st_size
|
||||
return sum(f.stat().st_size for f in path.rglob('*') if f.is_file())
|
||||
|
||||
|
||||
def _assert_executable_execution(exe_path: Path):
|
||||
if sys.platform == "darwin" and exe_path.is_dir() and exe_path.name.endswith(".app"):
|
||||
exe_path = exe_path / "Contents" / "MacOS" / exe_path.stem
|
||||
|
||||
assert exe_path.exists(), f"未找到生成的 EXE/二进制 文件: {exe_path}"
|
||||
start_t = time.time()
|
||||
proc = subprocess.run([str(exe_path)], capture_output=True, text=True, timeout=20, cwd=str(exe_path.parent))
|
||||
|
||||
assert proc.returncode == 0, f"程序运行报错 (Code {proc.returncode}):\n{proc.stderr}"
|
||||
assert "__QP_ASSERT__|42|QPYPACK_REAL_OK|__QP_ASSERT_END__" in proc.stdout, f"输出不符,资源提取失败:\n{proc.stdout}"
|
||||
|
||||
size_mb = _get_size(exe_path) / (1024 * 1024)
|
||||
log_pass(f"产物实机拉起验证通过!耗时: {time.time() - start_t:.2f}s | 体积: {size_mb:.2f} MB | 静态资源捆绑读取正常")
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# E2E 测试核心引擎: 完整模拟 MainWindow 界面交互与打包
|
||||
# =====================================================================
|
||||
def run_e2e_via_mainwindow(engine_name: str, tmp_dir: Path, is_onefile: bool):
|
||||
"""
|
||||
通过直接实例化 MainWindow 并触发界面事件,模拟真实用户的打包全流程。
|
||||
这能保证测试紧跟 UI 升级,覆盖完整的 "界面配置 -> 参数生成 -> 线程打包" 链路。
|
||||
"""
|
||||
from PySide6.QtCore import QEventLoop, QTimer
|
||||
from qpypack.main import MainWindow
|
||||
|
||||
sandbox = Path(tmp_dir)
|
||||
entry_file = _create_mock_project(sandbox)
|
||||
|
||||
# 1. 实例化主窗口 (触发所有的初始化和配置读取)
|
||||
window = MainWindow()
|
||||
|
||||
# 2. 模拟用户拖拽源码文件到界面
|
||||
window.on_script_selected(str(entry_file))
|
||||
|
||||
# 等待分析线程(ScriptAnalysisThread)完成
|
||||
loop_wait = QEventLoop()
|
||||
timer_wait = QTimer()
|
||||
timer_wait.timeout.connect(loop_wait.quit)
|
||||
timer_wait.start(1000) # 等待1秒确保分析完毕
|
||||
loop_wait.exec()
|
||||
timer_wait.stop()
|
||||
|
||||
assert window.current_state == "ready", "脚本载入后状态机未变为 ready"
|
||||
|
||||
# 3. 模拟用户配置界面面板 (SettingsPanel)
|
||||
sp = window.settings_panel
|
||||
sp.engine_combo.setCurrentText(engine_name)
|
||||
sp.rb_onefile.setChecked(is_onefile)
|
||||
sp.rb_onedir.setChecked(not is_onefile)
|
||||
sp.noconsole_check.setChecked(True)
|
||||
sp.enable_sign_check.setChecked(False) # 测试环境关闭签名防阻断
|
||||
|
||||
# 设置输出目录到沙箱中
|
||||
sp.out_mode_combo.setCurrentIndex(1)
|
||||
sp.out_dir_edit.setText(str(sandbox / "dist"))
|
||||
|
||||
# 4. 模拟用户拖入附加资源 (assets 文件夹)
|
||||
window.on_main_resources_dropped([str(entry_file.parent / "assets")])
|
||||
|
||||
# 5. 模拟点击【开始构建】
|
||||
window.start_pack()
|
||||
assert window.current_state == "building", "启动打包后,主窗口未进入 building 状态"
|
||||
|
||||
# 6. 使用事件循环等待 PackingThread 后台线程完成
|
||||
loop = QEventLoop()
|
||||
def check_status():
|
||||
# 轮询状态机是否退出 building
|
||||
if window.current_state in ("done", "failed"):
|
||||
loop.quit()
|
||||
|
||||
timer = QTimer()
|
||||
timer.timeout.connect(check_status)
|
||||
timer.start(500)
|
||||
loop.exec()
|
||||
timer.stop()
|
||||
|
||||
assert window.current_state == "done", f"【{engine_name}】打包失败!详细日志如下:\n{window.log_detailed.toPlainText()}"
|
||||
|
||||
# 7. 提取生成的程序名,并定位产物
|
||||
app_name = sp.name_edit.text().strip() or "MockTestApp"
|
||||
ext = ".exe" if sys.platform == "win32" else ""
|
||||
dist_dir = sandbox / "dist"
|
||||
|
||||
if sys.platform == "darwin" and sp.noconsole_check.isChecked():
|
||||
exe_path = dist_dir / f"{app_name}.app"
|
||||
else:
|
||||
if is_onefile:
|
||||
exe_path = dist_dir / f"{app_name}{ext}"
|
||||
else:
|
||||
# 文件夹模式:产物为 dist_dir/app_name/app_name.exe
|
||||
exe_path = dist_dir / app_name / f"{app_name}{ext}"
|
||||
|
||||
# 容错:Nuitka 在极少数情况下可能未重命名 .dist 文件夹,或者文件名带版本号
|
||||
if not exe_path.exists():
|
||||
fallback_dist = dist_dir / f"{app_name}.dist" / f"{app_name}{ext}"
|
||||
if fallback_dist.exists():
|
||||
exe_path = fallback_dist
|
||||
else:
|
||||
# 终极兜底:直接在目录里搜索可执行文件
|
||||
possible_exes = list((dist_dir / app_name).glob(f"*{ext}"))
|
||||
if possible_exes:
|
||||
exe_path = possible_exes[0]
|
||||
|
||||
# 8. 校验实机拉起
|
||||
_assert_executable_execution(exe_path)
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 7. PyInstaller E2E 测试
|
||||
# =====================================================================
|
||||
def test_07_pyinstaller_real_build():
|
||||
"""测试 7: 深度集成 UI 的 PyInstaller 真实打包与拉起测试"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 7/8] 深度集成测试: UI 操作 -> PyInstaller 构建 -> 实机拉起...{Colors.RESET}")
|
||||
try:
|
||||
import PyInstaller
|
||||
except ImportError:
|
||||
log_warn("缺少 PyInstaller,跳过测试")
|
||||
return
|
||||
|
||||
from PySide6.QtWidgets import QApplication
|
||||
app = QApplication.instance() or QApplication(["qp_test", "-platform", "offscreen"])
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix="qp_e2e_pyi_") as tmp_dir:
|
||||
start_t = time.time()
|
||||
# 测试 PyInstaller 的单文件模式
|
||||
run_e2e_via_mainwindow("PyInstaller", Path(tmp_dir), is_onefile=True)
|
||||
log_pass(f"PyInstaller E2E 完整链路测试通过,耗时: {time.time() - start_t:.2f}s")
|
||||
|
||||
clean_project_junk()
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 8. Nuitka E2E 测试
|
||||
# =====================================================================
|
||||
def test_08_nuitka_real_build():
|
||||
"""测试 8: 深度集成 UI 的 Nuitka 原生编译与拉起测试"""
|
||||
print(f"\n{Colors.BOLD}{Colors.CYAN}>>> [测试 8/8] 深度集成测试: UI 操作 -> Nuitka 原生编译 -> 实机拉起...{Colors.RESET}")
|
||||
try:
|
||||
import nuitka
|
||||
except ImportError:
|
||||
log_warn("缺少 Nuitka,跳过测试")
|
||||
return
|
||||
|
||||
from PySide6.QtWidgets import QApplication
|
||||
app = QApplication.instance() or QApplication(["qp_test", "-platform", "offscreen"])
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix="qp_e2e_nuitka_") as tmp_dir:
|
||||
start_t = time.time()
|
||||
# 测试 Nuitka 的文件夹模式 (Standalone)
|
||||
run_e2e_via_mainwindow("Nuitka", Path(tmp_dir), is_onefile=False)
|
||||
log_pass(f"Nuitka E2E 完整链路测试通过,耗时: {time.time() - start_t:.2f}s")
|
||||
|
||||
clean_project_junk()
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# 主调度入口
|
||||
# =====================================================================
|
||||
def main():
|
||||
print(f"""
|
||||
{Colors.CYAN}{Colors.BOLD}======================================================================
|
||||
🚀 QPyPack 全功能终极一体化自检与双引擎真实打包验证系统 (UI深度集成版)
|
||||
======================================================================{Colors.RESET}""")
|
||||
|
||||
tests = [
|
||||
("静态资源与工程配置", test_01_static_assets),
|
||||
("多语言包格式对齐与校验", test_02_locales_and_placeholders),
|
||||
("QPyPack 原生 AST 分析引擎", test_03_ast_engine),
|
||||
("QPyPack 核心配置与翻译引擎逻辑", test_04_core_logic),
|
||||
("Qt UI 主窗口状态机独立交互测试", test_05_ui_interaction),
|
||||
("Wheel 分发包沙箱构建测试", test_06_wheel_packaging),
|
||||
("PyInstaller E2E 链路验证 (单文件)", test_07_pyinstaller_real_build),
|
||||
("Nuitka E2E 链路验证 (文件夹)", test_08_nuitka_real_build),
|
||||
]
|
||||
|
||||
failed = False
|
||||
for title, func in tests:
|
||||
try:
|
||||
func()
|
||||
except Exception as e:
|
||||
failed = True
|
||||
log_fail(f"【{title}】未通过!原因: {e}")
|
||||
print(f"\n{Colors.RED}详细错误回溯:{Colors.RESET}")
|
||||
traceback.print_exc()
|
||||
break
|
||||
|
||||
# 无论成功失败,强制执行纯净清理
|
||||
clean_project_junk()
|
||||
|
||||
print(f"\n{Colors.BOLD}======================================================================{Colors.RESET}")
|
||||
if not failed:
|
||||
print(f"{Colors.GREEN}{Colors.BOLD} 🎉 [CONGRATULATIONS] 全部端到端深度集成测试 100% 顺利通过!{Colors.RESET}")
|
||||
print(f"{Colors.GREEN} 💡 你的所有 UI 修改、功能迭代、参数注入均完美运行,且一切残留已被销毁!{Colors.RESET}")
|
||||
print(f"{Colors.BOLD}======================================================================{Colors.RESET}\n")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print(f"{Colors.RED}{Colors.BOLD} 💥 [TEST FAILED] 发现程序缺陷!测试已中断,请根据上方回溯修复代码。{Colors.RESET}")
|
||||
print(f"{Colors.BOLD}======================================================================{Colors.RESET}\n")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user