转码工具页面功能
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# Python 项目集成指南
|
||||
|
||||
本指南说明如何将 `F:/04.python/04.python/uf2touft3` 项目与 Qt 应用程序集成。
|
||||
|
||||
## 两个方案对比
|
||||
|
||||
### 方案一:增强的 QProcess 方案 (推荐用于生产环境)
|
||||
|
||||
**优点:**
|
||||
- 简单稳定,不易出错
|
||||
- 进程隔离,不会影响主应用程序
|
||||
- Python 依赖问题独立解决
|
||||
- 调试方便
|
||||
|
||||
**缺点:**
|
||||
- 进程间通信开销
|
||||
- 无法直接共享内存
|
||||
|
||||
**状态:已实现并集成 ✅**
|
||||
|
||||
### 方案二:pybind11 嵌入方案 (高级选项)
|
||||
|
||||
**优点:**
|
||||
- 更紧密的集成
|
||||
- 可以直接调用 Python 函数
|
||||
- 更好的性能
|
||||
|
||||
**缺点:**
|
||||
- 配置复杂
|
||||
- 需要 C++ 编译环境
|
||||
- 调试困难
|
||||
- Python 全局解释器锁 (GIL) 问题
|
||||
|
||||
**状态:提供示例代码 ⚠️**
|
||||
|
||||
## 使用方案一 (推荐)
|
||||
|
||||
### 1. 确保 Python 环境可用
|
||||
|
||||
确保系统已安装 Python 3.8+,并且可以在命令行中运行:
|
||||
```bash
|
||||
python --version
|
||||
```
|
||||
|
||||
### 2. 确保 Python 项目完整
|
||||
|
||||
确保 `F:/04.python/04.python/uf2touft3` 目录包含所有必要文件:
|
||||
- `main.py`
|
||||
- `processCombination.py`
|
||||
- `config.ini`
|
||||
- 其他依赖的模块和配置文件
|
||||
|
||||
### 3. 使用 Qt 应用程序
|
||||
|
||||
直接运行编译好的 `Uft30ChangeCode.exe`,点击"开始转换"按钮即可调用 Python 代码。
|
||||
|
||||
## 构建方案二 (高级)
|
||||
|
||||
如果你想使用 pybind11 方案,按以下步骤:
|
||||
|
||||
### 1. 安装依赖
|
||||
|
||||
```bash
|
||||
pip install pybind11
|
||||
```
|
||||
|
||||
### 2. 创建构建目录
|
||||
|
||||
```bash
|
||||
cd python_bindings/pybind11_binding
|
||||
mkdir build
|
||||
cd build
|
||||
```
|
||||
|
||||
### 3. 配置 CMake
|
||||
|
||||
```bash
|
||||
cmake .. -G "MinGW Makefiles"
|
||||
# 或使用 Visual Studio
|
||||
# cmake .. -G "Visual Studio 16 2019" -A x64
|
||||
```
|
||||
|
||||
### 4. 编译
|
||||
|
||||
```bash
|
||||
cmake --build . --config Release
|
||||
```
|
||||
|
||||
### 5. 集成到 Qt 项目
|
||||
|
||||
在你的 Qt 代码中动态加载编译好的库。
|
||||
|
||||
## Python 项目的依赖
|
||||
|
||||
确保你的 Python 项目所需的所有依赖都已安装:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
*(需要在 uf2touft3 项目中创建 requirements.txt)*
|
||||
|
||||
## 故障排查
|
||||
|
||||
### Python 无法启动
|
||||
- 检查 Python 是否在 PATH 中
|
||||
- 尝试设置完整的 Python 路径
|
||||
- 检查是否有多个 Python 版本
|
||||
|
||||
### 模块导入错误
|
||||
- 确保工作目录设置正确
|
||||
- 检查所有依赖的模块是否都在 Python 路径中
|
||||
- 检查 `config.ini` 中的路径配置是否正确
|
||||
|
||||
### 中文路径问题
|
||||
- 确保所有路径使用 UTF-8 编码
|
||||
- 避免在路径中使用特殊字符
|
||||
|
||||
## 自定义配置
|
||||
|
||||
如需修改 Python 脚本路径,可以编辑 `mainwindow.cpp` 中的配置:
|
||||
```cpp
|
||||
QString scriptPath = "F:/04.python/04.python/uf2touft3/main.py";
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
# Python Bindings for UFT30 Change Code
|
||||
|
||||
本目录包含将 Python 项目编译为可被 Qt 调用的库的相关代码。
|
||||
|
||||
## 方案一:使用 pybind11 (推荐用于高性能集成)
|
||||
|
||||
此方案创建一个 C++ 库,直接嵌入 Python 解释器并调用 Python 代码。
|
||||
|
||||
## 方案二:增强的 QProcess 方案 (推荐用于简单集成)
|
||||
|
||||
此方案保持使用子进程调用,但增加更好的错误处理、进度显示等功能。
|
||||
|
||||
## 构建说明
|
||||
|
||||
### 前置要求
|
||||
|
||||
- Python 3.8+ (开发版,包含头文件)
|
||||
- CMake 3.15+
|
||||
- Visual Studio 2019+ 或 MinGW-w64
|
||||
- pybind11 (可以通过 pip 安装)
|
||||
@@ -0,0 +1,44 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(uf2touft3_binding VERSION 1.0.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# 查找 Python
|
||||
find_package(Python3 COMPONENTS Interpreter Development REQUIRED)
|
||||
|
||||
# 尝试查找 pybind11
|
||||
# 方法 1: 通过 pip 安装的 pybind11
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -m pybind11 --cmakedir
|
||||
OUTPUT_VARIABLE PYBIND11_CMAKE_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
if(PYBIND11_CMAKE_DIR)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${PYBIND11_CMAKE_DIR})
|
||||
endif()
|
||||
|
||||
find_package(pybind11 REQUIRED)
|
||||
|
||||
# 创建 Python 模块
|
||||
pybind11_add_module(uf2touft3_binding uf2touft3_binding.cpp)
|
||||
|
||||
# Windows 特定设置
|
||||
if(WIN32)
|
||||
set_target_properties(uf2touft3_binding PROPERTIES
|
||||
SUFFIX ".pyd"
|
||||
)
|
||||
endif()
|
||||
|
||||
# 安装目标
|
||||
install(TARGETS uf2touft3_binding
|
||||
LIBRARY DESTINATION .
|
||||
RUNTIME DESTINATION .
|
||||
)
|
||||
|
||||
message(STATUS "Python3 executable: ${Python3_EXECUTABLE}")
|
||||
message(STATUS "Python3 include dirs: ${Python3_INCLUDE_DIRS}")
|
||||
message(STATUS "Python3 libraries: ${Python3_LIBRARIES}")
|
||||
message(STATUS "pybind11 found: ${pybind11_FOUND}")
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/embed.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
// 全局解释器持有对象
|
||||
py::scoped_interpreter* g_python_interpreter = nullptr;
|
||||
|
||||
// 初始化 Python 解释器
|
||||
extern "C" __declspec(dllexport) bool InitializePython()
|
||||
{
|
||||
try {
|
||||
if (!g_python_interpreter) {
|
||||
g_python_interpreter = new py::scoped_interpreter();
|
||||
}
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Failed to initialize Python: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 清理 Python 解释器
|
||||
extern "C" __declspec(dllexport) void FinalizePython()
|
||||
{
|
||||
if (g_python_interpreter) {
|
||||
delete g_python_interpreter;
|
||||
g_python_interpreter = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行 doWork 函数
|
||||
extern "C" __declspec(dllexport) bool RunConversion(const char* script_path)
|
||||
{
|
||||
try {
|
||||
if (!g_python_interpreter) {
|
||||
std::cerr << "Python interpreter not initialized!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 添加脚本路径到 sys.path
|
||||
py::module sys = py::module::import("sys");
|
||||
py::object path = sys.attr("path");
|
||||
|
||||
// 获取脚本目录
|
||||
std::string script_dir = script_path;
|
||||
size_t last_sep = script_dir.find_last_of("/\\");
|
||||
if (last_sep != std::string::npos) {
|
||||
script_dir = script_dir.substr(0, last_sep);
|
||||
}
|
||||
|
||||
// 添加到 sys.path
|
||||
path.attr("insert")(0, script_dir);
|
||||
|
||||
// 导入脚本模块
|
||||
py::module script_module = py::module::import("main");
|
||||
|
||||
// 调用 doWork 函数
|
||||
script_module.attr("doWork")();
|
||||
|
||||
return true;
|
||||
} catch (const py::error_already_set& e) {
|
||||
std::cerr << "Python error: " << e.what() << std::endl;
|
||||
return false;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 简单的 C API 封装
|
||||
PYBIND11_MODULE(uf2touft3, m) {
|
||||
m.doc() = "UFT2 to UFT3 code conversion module";
|
||||
|
||||
m.def("initialize", &InitializePython, "Initialize Python interpreter");
|
||||
m.def("finalize", &FinalizePython, "Finalize Python interpreter");
|
||||
m.def("run_conversion", &RunConversion, "Run the conversion process",
|
||||
py::arg("script_path"));
|
||||
}
|
||||
Reference in New Issue
Block a user