指定新迁移计划
This commit is contained in:
+84
-9
@@ -1,6 +1,6 @@
|
||||
# FancyInput WPF → Qt 6 (QML + C++) 迁移方案
|
||||
|
||||
> 版本:v2.0 · 日期:2026-08-19 · 状态:待评审
|
||||
> 版本:v2.1 · 日期:2026-08-20 · 状态:待评审
|
||||
> 源项目:`WPF\FancyInput`(.NET 8.0 WPF,约 132 文件 / 24,000 行)
|
||||
> 目标框架:**Qt 6.8.3(MinGW 13.1.0 x64 + CMake + QML)**
|
||||
> 目标:**UI 布局完全一致、逻辑相同**,代码用 QML + C++ 重写
|
||||
@@ -9,6 +9,76 @@
|
||||
|
||||
---
|
||||
|
||||
## 新会话快速上手(★ 新开会话先读这里)
|
||||
|
||||
> 本工程已通过 **阶段 0(Hello World)+ 构建基础设施**,全部验证通过。以下信息足以让一个新会话立刻上手,详细踩坑记录见仓库记忆 `/memories/repo/qt-build-notes.md`(新会话会自动加载)。
|
||||
|
||||
### 当前工程结构(已验证可构建可运行)
|
||||
|
||||
```
|
||||
Qt\
|
||||
├── CMakeLists.txt # 顶层工程(两个 QML 模块 + 部署裁剪)
|
||||
├── CMakePresets.json # MinGW_64_Debug / MinGW_64_Release 预设
|
||||
├── MIGRATION_PLAN.md # 本文档
|
||||
├── .vscode\settings.json # qmlls import paths + cmake preset
|
||||
├── src\
|
||||
│ ├── main.cpp # QGuiApplication + addImportPath("qrc:/") + loadFromModule
|
||||
│ └── qml\
|
||||
│ ├── Main.qml # 主窗口(ApplicationWindow 600×480,阶段 0 骨架)
|
||||
│ └── controls\ # ★ 用户自定义控件目录(URI: FancyInput.Controls)
|
||||
│ └── Theme.qml # 全局主题单例(pragma Singleton)
|
||||
├── bin\{Debug,Release}\ # exe + windeployqt 部署的 Qt 运行库(最终产物)
|
||||
└── build\MinGW_64_{Debug,Release}\ # 中间产物 + QML 模块目录(qmlls 用)
|
||||
```
|
||||
|
||||
### QML 模块架构(关键!)
|
||||
|
||||
| 模块 | 类型 | URI | 内容 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `FancyInputControls` | **静态库**(`STATIC` 关键字写在 `qt_add_qml_module` 内) | `FancyInput.Controls` | `src/qml/controls/*.qml`(GLOB 自动收集) | 以后**新增控件只需放 .qml 文件,无需改 CMakeLists** |
|
||||
| `FancyInputQt` | 可执行文件主模块 | `FancyInputQt` | `src/qml/Main.qml` | `DEPENDENCIES FancyInputControls` |
|
||||
|
||||
必须记住的三条铁律(踩过坑):
|
||||
1. **静态 QML 模块必须链接插件 target**:`target_link_libraries(FancyInputQt PRIVATE FancyInputControls FancyInputControlsplugin ...)`,否则运行时报 "plugin FancyInputControlsplugin not found";
|
||||
2. **`pragma Singleton` 不会被自动识别**:必须 `set_source_files_properties(Theme.qml PROPERTIES QT_QML_SINGLETON_TYPE TRUE)` **且放在 `qt_add_qml_module` 调用之前**;
|
||||
3. **`QT_QML_OUTPUT_DIRECTORY` 必须设置**:在**所有** `qt_add_qml_module` 之前写 `set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")`——否则库模块输出到 build 根目录(Qt6QmlMacros.cmake:1430 警告)且 qmlls 找不到模块。
|
||||
|
||||
### 构建与验证命令(终端)
|
||||
|
||||
```powershell
|
||||
# 终端 PATH(每次新终端都要先执行)
|
||||
$env:Path = "D:/Qt/6.8.3/mingw_64/bin;D:/Qt/Tools/mingw1310_64/bin;C:\Windows\System32;C:\Windows"
|
||||
Set-Location "d:\Projects\FancyInput\Qt"
|
||||
|
||||
# 配置(仅首次或 CMakeLists 变更时)
|
||||
& "C:\Program Files\CMake\bin\cmake.exe" --preset MinGW_64_Debug
|
||||
|
||||
# 编译(每次改完代码;干净重建加 --clean-first)
|
||||
& "C:\Program Files\CMake\bin\cmake.exe" --build --preset MinGW_64_Debug
|
||||
|
||||
# 运行验证(GUI 程序无控制台输出,用窗口标题确认)
|
||||
# 先切干净 PATH 再运行,验证独立运行(不带 Qt bin 目录):
|
||||
$env:Path = "C:\Windows\System32;C:\Windows"
|
||||
Start-Process "bin\Debug\FancyInputQt.exe" -PassThru | Select-Object MainWindowTitle
|
||||
# 期望标题:"FancyInput · Qt 迁移版(阶段 0)"
|
||||
|
||||
# QML 模块解析验证(无输出 = 成功)
|
||||
& "D:\Qt\6.8.3\mingw_64\bin\qmllint.exe" -I build/MinGW_64_Debug -I D:/Qt/6.8.3/mingw_64/qml src/qml/Main.qml src/qml/controls/Theme.qml
|
||||
```
|
||||
|
||||
### 许可状态(2026-08-20 已核对,全部 LGPL 安全 ✅)
|
||||
|
||||
- 部署的 Qt DLL 全部为 LGPL v3 官方模块(SPDX 核对 qtbase/qtdeclarative/qtsvg:`Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only`,开源版按 LGPL v3 使用);
|
||||
- MinGW 运行时 DLL(libgcc_s_seh-1/libstdc++-6/libwinpthread-1):GPLv3 + **GCC Runtime Library Exception**(`D:\Qt\Tools\mingw1310_64\licenses\gcc\COPYING.RUNTIME` 已确认),允许闭源商用;
|
||||
- **Qt6VirtualKeyboard(GPL v3)已被 CMakeLists 的 `GPL_COMPONENTS` 块强制裁剪**(windeployqt 会隐式部署,App 实际不用)——这是防御性安全网,不是已部署组件;
|
||||
- bin/Release 实测 24 个 DLL(21 Qt6 + 3 MinGW 运行时)+ qml 模块仅 {QML, QtQml, QtQuick},无任何 GPL 文件。
|
||||
|
||||
### 下一步
|
||||
|
||||
**进入阶段 1(通用函数与数据结构)**,从 `src\core\common\Enums.h` 开始。详见下文第四、五节的分阶段计划。
|
||||
|
||||
---
|
||||
|
||||
## 〇、许可合规策略(重要)
|
||||
|
||||
**核心原则:全部组件要么是 LGPL 动态链接(可免费闭源商用),要么是宽松许可(MIT/zlib/BSD),一律避开 GPL/AGPL。**
|
||||
@@ -259,14 +329,16 @@ Qt\
|
||||
**每阶段通用验收流程**(适用于所有阶段):
|
||||
1. 编写/调整代码 → 2. `cmake --build` 就地编译 → 3. 运行程序验证 → 4. 有变化才进入下一步
|
||||
|
||||
**每阶段通用的构建命令**(`Qt\` 目录下):
|
||||
**每阶段通用的构建命令**(`Qt\` 目录下,已改用 CMakePresets):
|
||||
```powershell
|
||||
# 终端 PATH
|
||||
$env:Path = "D:/Qt/6.8.3/mingw_64/bin;D:/Qt/Tools/mingw1310_64/bin;C:\Windows\System32;C:\Windows"
|
||||
# 配置(仅首次或 CMakeLists 变更时)
|
||||
cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH=D:/Qt/6.8.3/mingw_64 -DCMAKE_BUILD_TYPE=Debug
|
||||
& "C:\Program Files\CMake\bin\cmake.exe" --preset MinGW_64_Debug
|
||||
# 编译(每次改完代码)
|
||||
cmake --build build -j
|
||||
# 运行
|
||||
.\build\FancyInputQt.exe
|
||||
& "C:\Program Files\CMake\bin\cmake.exe" --build --preset MinGW_64_Debug
|
||||
# 运行(exe 在 bin\Debug\ 下,非 build 目录)
|
||||
.\bin\Debug\FancyInputQt.exe
|
||||
```
|
||||
|
||||
---
|
||||
@@ -278,10 +350,12 @@ cmake --build build -j
|
||||
- [x] `Qt\CMakeLists.txt`:`find_package(Qt6 COMPONENTS Core Gui Qml Quick QuickControls2)`;`qt_add_executable(FancyInputQt ...)` + `qt_add_qml_module`
|
||||
- [x] `src\main.cpp`:`QGuiApplication` + `QQmlApplicationEngine` 加载 QML(`objectCreationFailed` 兜底退出)
|
||||
- [x] `src\qml\Main.qml`:`ApplicationWindow` 600×480,标题 "FancyInput · Qt 迁移版(阶段 0)"
|
||||
- [x] `src\qml\Theme.qml`:全局主题单例(主色 `#651F65`、背景 `#1E1E24`、字体 `Cascadia Mono`)
|
||||
- [x] `src\qml\controls\Theme.qml`:全局主题单例(主色 `#651F65`、背景 `#1E1E24`、字体 `Cascadia Mono`)——**注意在 `controls\` 目录**(属 `FancyInput.Controls` 模块),不在 qml 根目录;用 `Theme.xxx` 引用
|
||||
- [x] 双 QML 模块架构:`FancyInput.Controls`(静态库,GLOB 自动收集 controls/ 下所有 .qml)+ `FancyInputQt`(主模块)——以后加控件零改 CMakeLists
|
||||
- [x] 构建基础设施:CMakePresets(Debug/Release)、windeployqt 部署 + 体积裁剪、qmlls/qmllint 无警告
|
||||
- [ ] 资源目录 `resources\icons\`(拷贝 Icon.png/ico,阶段 4 主界面时补)
|
||||
|
||||
**产出**:`FancyInputQt.exe` 可运行,窗口显示、主题色正确(已验证,2026-08-19)。
|
||||
**产出**:`bin\Debug\FancyInputQt.exe` 可运行,窗口显示、主题色正确(已验证,2026-08-19 至 08-20)。
|
||||
|
||||
### 阶段 1:通用函数与数据结构(纯 C++,不依赖 UI)
|
||||
|
||||
@@ -373,7 +447,7 @@ cmake --build build -j
|
||||
- [ ] 在线更新检查(QNetworkAccessManager,API 地址照搬)
|
||||
- [ ] 虚拟手柄完善(ViGEm 若未在前置做)+ 终端页(QProcess cmd/PowerShell)
|
||||
- [ ] 管理员自提权、单实例、命令行参数(.fip/.fips 打开)
|
||||
- [ ] `windeployqt` 发布打包 + LGPL 合规文件(LGPLv3 文本 + Qt 版本声明)
|
||||
- [ ] `windeployqt` 发布打包 + LGPL 合规文件(LGPLv3 文本 + Qt 版本声明)——**许可已核对(2026-08-20)**:全部部署组件 LGPL 安全(见文首快速上手章节),打包时需附 LGPLv3 文本 + 保留 DLL 可替换性
|
||||
- [ ] UI 逐屏对照验收 + 行为对照验收
|
||||
|
||||
---
|
||||
@@ -442,3 +516,4 @@ cmake --build build -j
|
||||
5. **虚拟手柄(ViGEm)**:**已确认不做**;HidHide(GPL)同样不迁移
|
||||
6. **范围**:按上表全功能迁移,宏系统/图像编辑器/在线更新延后(已定)
|
||||
7. **代码中已注释掉的逻辑**(HidHide、MirrorGamepad、ConsoleWindow 等)是否一并迁移?建议不迁(保持与 WPF 行为一致)
|
||||
8. **第三方依赖 DLL 存放方案**:待确认是否按 `bin/<config>/thirdparty/` 子目录存放第三方库(SDL3/ViGEmClient 等),与 Qt DLL 分离,便于许可管理(尚未实施,等 SDL3 接入时确认)
|
||||
|
||||
Reference in New Issue
Block a user