# 川大 C++/LinuxC 课程「02. Qt 方向」代码仓库

本仓库把川大 wiki「02. Qt 方向」的课程代码整理成 **CMake 管理**的可编译运行的项目：
每个示例 = 一个独立 `add_executable` 目标，可单独构建运行。所有源码由生成器
（`tools/gen_*.py`）从抓取的 wiki 代码块产出，对 wiki 原始代码的每一处修正都记录在
`docs/ERRATA*.md`（透明可审计）。

> 标准基线：**C17 / C++17**（严格、不允许编译器扩展）。版本相关的概念另由
> `tools/std_probe.py` + `tools/demo_versions/` 跨版本演示（见 `docs/VERSION_NOTES.md`）。

## 仓库结构

```
qt-course/
├── CMakeLists.txt          顶层：C17/C++17 严格；option(BUILD_QT_PART)；隔离 Qt 版本断言
├── p01/                    Part 1：C/C++ 强化（控制台，host gcc/g++ 构建）144 个目标
│   ├── ch02 … ch09/        深缩写目录：p01/ch04/s03/ 这种形式
├── p03/                    Part 3：Qt 桌面（需隔离 Qt 5.14.2）29 个目标
│   ├── ch02 … ch11/        含 .qrc 资源、assets 占位图、rundata 样例数据
├── tools/
│   ├── gen_sources.py      共享引擎：标题解析 page_outline()、语言判定、common_fix()
│   ├── gen_part1.py        Part1 生成器（exact_fix / dedupe / emit_console）
│   ├── gen_part3.py        Part3 生成器（Qt 外壳 / rewrite / AUTOMOC / .qrc）
│   ├── file_name_map.py    (pageId, section) → 英文文件名词根（全覆盖）
│   ├── std_probe.py        跨 -std= 编译探针（任务 1 机制）
│   ├── demo_versions/      版本相关论断的最小演示片段
│   ├── run.sh / run_qt.sh  宿主机运行 p01 / p03 目标（Qt 走 LD_LIBRARY_PATH 隔离）
│   ├── install_qt_host.sh  宿主机直装隔离 Qt 5.14.2 + Qt Creator 4.11.0 到 .qt514/
│   └── wiki_data/          抓取的 wiki 正文+代码块（生成器输入，只读）
├── docs/
│   ├── ERRATA.md           Part1 代码修正记录（自动生成）
│   ├── ERRATA_part3.md     Part3 Qt 代码修正记录（自动生成）
│   ├── VERSION_NOTES.md    版本相关概念验证记录
│   └── SOURCE_PAGES.md     wiki 页面 → 目录映射表
└── .qt514/                 隔离的 Qt 5.14.2 工具链（aqtinstall 装在仓库内，gitignore）
```

## 快速开始

### Part 1（C/C++ 强化，无需 Qt）

```bash
cmake -S . -B build -G Ninja -DBUILD_QT_PART=OFF -DCMAKE_BUILD_TYPE=Debug
cmake --build build                      # 144 个目标全绿
tools/run.sh <target>                    # 例：tools/run.sh p1c04_03_01
cmake --build build --target all_p01_ch04_s03   # 只构建某章
```

### Part 3（Qt 桌面，需隔离 Qt 5.14.2）

```bash
# 一次性：装隔离 Qt 5.14.2（装到 .qt514/，不碰系统 Qt 5.15）
tools/install_qt_host.sh

cmake -S . -B build -G Ninja -DBUILD_QT_PART=ON \
      -DCMAKE_PREFIX_PATH=$PWD/.qt514/5.14.2/gcc_64 -DCMAKE_BUILD_TYPE=Debug
cmake --build build                      # 144 + 29 = 173 个目标全绿

# 运行（隔离 Qt，靠 LD_LIBRARY_PATH）：
tools/run_qt.sh <target>                 # 例：tools/run_qt.sh qpainter_basic
# 离屏/自动化验证（无 X 也可）：
QT_QPA_PLATFORM=offscreen tools/run_qt.sh <target>
```

> **隔离验证**：`ldd build/p03/.../<target>` 显示所有 Qt 库只解析到 `.qt514/`，
> 零系统 Qt 引用。顶层 `CMakeLists.txt` 有版本断言——误连系统 Qt 5.15 会 `FATAL_ERROR`。
> 每个 Qt GUI 目标注入 `QTimer::singleShot`，仅当 `QT_QPA_PLATFORM=offscreen` 时才在
> 200ms 后自动退出，便于离屏验证；正常运行窗口保持打开，不自动退出。

## 目录命名（深缩写）

按「part / 章 / 节」三级缩写：

| 含义 | 形式 | 例 |
|---|---|---|
| part（不编号） | `pNN` | `p01`=Part1，`p03`=Part3 |
| 章 | `chNN` | `ch04`=第 4 章 类和对象 |
| 节 | `sNN` | `s03`=第 3 节 对象的构造和析构 |

完整映射见 `docs/SOURCE_PAGES.md`。源文件名为英文蛇形（见 `tools/file_name_map.py`）。

## 重新生成全部源码（幂等）

改了生成器后，先清空再重生成：

```bash
rm -rf p01 p03 build && python3 tools/gen_part1.py && python3 tools/gen_part3.py
```

## 版本概念演示（任务 1）

```bash
# 把一段代码在多个 -std= 下编译，看「某概念在哪个版本成立」
tools/std_probe.py --lang c --file tools/demo_versions/kr_implicit_int.c \
    --standards c89,c99,c11,c17 --pedantic-errors

# 结论汇总见 docs/VERSION_NOTES.md（含 K&R 隐式 int、三目左值、void* 转换、
# enum 赋整、动态异常规范 等跨版本对照）
```

## 关键约束（红线）

- **不修改** `tools/wiki_data/` 中的原始抓取数据（生成器只读输入）。
- 每处对 wiki 代码的修正都 `record_erratum()` 进 `docs/ERRATA*.md`（透明可审计）。
- 隔离 Qt：构建/运行一律走 `.qt514/`，**不碰系统 Qt 5.15**。
- 每个示例相对隔离：一文件一目标；不跨块合并造符号冲突。

详细续接说明见 `HANDOFF.md`。
