- docs/teaching/OUTLINE.md、slides/day1-5.html、index.html:替换此前自定义的 4 天方案,严格对齐 docs/TRAINING_PLAN_2026.md「C++方向」Day1-5 课堂内容 (Day6-10 为纯项目实作,不在教案范围) - docs/teaching/examples/:官方方案书要求但仓库 p03/(wiki 抓取内容) 未覆盖的 QSS/Model-View/JSON/QThread/QPropertyAnimation/QStateMachine 六个技术点, 各补一个最小可运行示例 + README 教学文档,均已离屏验证跑通;手工维护, 不属于 gen_part3.py 生成产物 - 根 CMakeLists.txt:接入 docs/teaching/examples 构建(BUILD_QT_PART 分支内), 不改动生成器管理的 p01/p03 CMakeLists - 任务卡改为目标/验收标准/基础知识参考三段式模板,custom.css 配套新增样式 - docs/teaching/PRETEST.md:10 题 10 分钟 C++ 摸底测验,验证教案假定的受众 基础是否成立,并与 OUTLINE.md §0 的分层预案挂钩
22 KiB
教案大纲 —「C++/Qt 方向」5 天实训(对齐官方方案书 Day1–5)
配套材料:
docs/teaching/slides/day1.html…day5.html(reveal.js 交互幻灯片, 已 vendor 进仓库,离线可用,见文末「材料与播放方式」)。依据:
docs/TRAINING_PLAN_2026.md《四川大学软件学院 2026 年夏 C/C++ 项目实习 实训方案书 V1.2》「五、执行计划 (二) C++方向」。方案书 C++方向共 10 天, Day6–10 是纯项目实作(学员编码+教员指导+成果展示),没有课堂讲授内容, 不在本教案范围内;本教案覆盖 Day1–5 的全部课堂教学。
0. 受众假设与本轮调整说明(显式声明,供随时纠偏)
本教案假定学员已掌握 C++ 基础语法与面向对象概念,方案书对 Day1 下午的官方
定位就是"C++ 高级程序开发回顾和提升"——复习强化,不是零基础教学。这条假设
不是拍脑袋定的,Day1 模块 B 开始前建议先用
docs/teaching/PRETEST.md(10 题、10 分钟摸底测验)实测一次,
按测验结果决定是照原节奏推进还是回退到语法讲解(该文件里有对应的分层预案)。
与仓库里此前一版教案的关系:docs/teaching/ 下此前有一版自定义 4 天教案
(3 天 C++ 强化 + 1 天 Qt,讲:练 ≈ 1:3),是当时按用户选定的另一种日程假设做的。
本版替换那一版,严格对齐官方 10 天方案书 C++ 方向的 Day1–5 结构——差异很
大:官方结构里 C++ 只占 Day1 下午半天(其余 4.5 天都是 Qt),所以 C++ 内容从
原来的 3 天深度压缩为半天的精选亮点 + 自学指针,不再逐章深入;Qt 内容则
从原来压缩的 1 天摊开到 Day2–5 四天,覆盖面明显更广。
内容缺口的显式处理(这是本轮设计的关键决策,写清楚以便后续纠偏):
- 官方方案书 Day3–4 提到的 Model/View、JSON 解析、QThread 多线程、
QPropertyAnimation 动画、QStateMachine 状态机,仓库
p03/(wiki 抓取内容) 原本完全没有对应代码。本轮已在docs/teaching/examples/补齐 6 个最小可 运行示例(含配套 README 教学文档),构建已接入根CMakeLists.txt(add_teaching_example分组,见该文件注释),均已QT_QPA_PLATFORM=offscreen离屏验证跑通。这些示例是手工维护的教学补充,不属于tools/gen_part3.py的生成产物,重新生成p01/p03不会影响它们。 - 以下两项仍按"纯概念 / 自学"处理,不写可运行代码(原因见括号):
- Vcpkg 包管理器(Day1)——需要安装真实 vcpkg 工具链,超出"最小示例" 范畴,且与仓库当前依赖面(host gcc/g++ + 隔离 Qt 5.14.2)无关;
- OpenCV 人脸/目标检测(Day5)——方案书原文本身就标注"可选择",属于 非必修拓展,引入 OpenCV 会新增一条完整的三方库工具链。
- 如果后续需要这两项也做成可运行示例,请明确提出——这会涉及新增外部依赖, 需要单独确认。
1. 总体目标
- 学员能说出 C++ 相对 C 的关键扩展机制在哪个标准版本成立/失效(复习向, 不重新从语法教起)。
- 学员能读懂并扩展一个 Qt 桌面小程序,覆盖信号槽、控件、布局/QSS、事件、 绘图、文件 IO/JSON、Model/View、多线程、动画/状态机中的大多数(覆盖面 是 Qt 教学的重点,深度服从进度)。
- 每天结束都有一个可运行、可验证的产出。
- 学员能看懂本次实训的项目管理流程(JIRA/Git/OASIS),为 Day6–10 的项目实作 打基础。
2. 课时结构
每天 6 课时(45 分钟/课时 ×6 = 270 分钟),分两个模块。Day1 上午是开训/职业 素养内容,没有编码练习,用讨论型任务卡代替;其余全部保持"讲:练"结构:
| 模块 | 时长 | 讲授 | 练习/讨论 | 小结/答疑 |
|---|---|---|---|---|
| 模块 A(上午,3 课时) | 135min | 35min | 95min | 5min |
| 模块 B(下午,3 课时) | 135min | 35min | 95min | 5min |
Day2–5 讲:练 ≈ 1:2.7;Day1 模块 A 是讨论型任务(不追求"练"的编码产出), 模块 B(C++/CMake/Vcpkg)内容压缩,35min 讲授只做"巡礼式"精选亮点。
3. 五天总览
| Day | 官方主题 | 模块 A | 模块 B |
|---|---|---|---|
| 1 | 开训 + C++回顾/工具链 | 团队建设/Scrum/C++企业应用(讨论,无编码) | C++精选回顾 + CMake实操 + Vcpkg概念 |
| 2 | Qt开发环境/信号槽/基础控件 | 项目结构/信号槽 p03/ch02–04 |
控件/布局/QSS美化 p03/ch08 + 新示例 qt_qss_styling → 计算器案例 |
| 3 | 高级控件/事件/文件IO/JSON | Model/View 新示例 + 事件拦截 p03/ch09 |
文件IO p03/ch11 + JSON 新示例 → 本地数据存储案例 |
| 4 | 2D绘图/多线程/动画/状态机 | 2D绘图 p03/ch10 + QThread 新示例 |
动画+状态机新示例 → 交互式小游戏案例 |
| 5 | 团队协同/综合案例/OpenCV可选 | 团队协同开发(概念,用方案书图) | 综合案例复盘 + OpenCV/AI 自学指针 |
标注约定:讲 = 课堂演示讲解,练 = 学员必须动手完成,参考 = 不在 课堂展开、留作课后自学。所有清单都是精选而非全集。
Day 1 — 开训 + C++ 回顾/工具链
模块 A:团队建设 / 敏捷 Scrum / C++ 在企业中的应用(讨论型,无编码)
讲(35min):
| 内容 | 素材 |
|---|---|
| 团队建设与文化、实训安排与考评要求 | 口头介绍,无固定素材 |
| 项目开发过程管理(JIRA/Git/OASIS/Wiki) | docs/TRAINING_PLAN_2026.md 「七、质量保证」+ 图 docs/images/training_service_flow.png、quality_four_platforms.png |
| 敏捷 Scrum 项目开发管理 | 同上「服务流程图」里的迭代环节(需求分析→需求评审→项目研发→阶段评审→项目测试) |
| C++ 在企业中的应用 | 口头介绍,结合往届案例(如有) |
讨论(95min,分组,非编码):
- 任务卡 1
- 目标:结合服务流程图,说清楚本组打算怎么分工使用 Jira(任务跟踪)+ Git(代码版本管理)
- 验收标准:每组提交一句话分工说明(谁负责建 Jira 看板/谁负责 Git 仓库初始化),能在图上指出对应环节
- 基础知识 · 参考:
docs/images/training_service_flow.png;docs/TRAINING_PLAN_2026.md「七、质量保证 (一)(二)」
- 任务卡 2
- 目标:选定实训期间打算做的项目方向(Linux C 方向 或 C++/Qt 方向的备选商业项目之一)
- 验收标准:每组报出项目名称 + 一句话说明选择理由
- 基础知识 · 参考:
docs/TRAINING_PLAN_2026.md「八、备选商业项目介绍」
模块 B:C++ 环境搭建 / 高级程序回顾 / CMake / Vcpkg(压缩讲解)
讲(35min,巡礼式,只挑「学过但容易讲不透」的点,不逐章展开):
| 知识点 | 文件 | 一句话说明 |
|---|---|---|
| namespace 作用域 | p01/ch03/namespace_syntax.cpp |
对照 docs/ERRATA.md,"作用域"不是"文件顺序" |
| 函数重载决议 | p01/ch03/function_overload_mechanism.cpp |
名字改写与重载集合,二义性从哪来 |
| 引用的本质 | p01/ch03/reference_essence.cpp |
"引用是自动解引用的 const 指针" |
| 虚析构与内存泄漏 | p01/ch04/s08/virtual_dtor_purpose.cpp |
基类指针 delete 派生类对象的经典坑 |
| 模板与 STL 速览 | p01/ch05/class_template_basics.cpp、p01/ch09/s03/vector_iterator.cpp |
泛型编程 + 容器/迭代器,只点名不展开 |
| CMake 项目构建 | 本仓库 CMakeLists.txt、p03/CMakeLists.txt |
用真实项目当教材:option(BUILD_QT_PART)、add_subdirectory、每个示例一个 add_executable 目标 |
| Vcpkg 包管理器(概念,无演示) | 无仓库代码 | C++ 生态的包管理器,解决"第三方库怎么装、怎么被 CMake 找到"的问题;本仓库用的是"隔离 Qt 手动装"而非 vcpkg,两种思路都要认识 |
练(95min):
- 任务卡 1 · 走一遍真实构建流程
- 目标:独立完成本仓库 Part1 的配置+构建,不看着教师操作
- 验收标准:
cmake -S . -B build -G Ninja -DBUILD_QT_PART=OFF配置成功;cmake --build build144 个目标全绿;能说出option(BUILD_QT_PART)的作用 - 基础知识 · 参考:仓库根
CMakeLists.txt;CMake 官方文档 Tutorial(选读·需联网)
- 任务卡 2 · 修一个真实的坑
- 目标:从
docs/ERRATA.md挑 2 条记录,在对应源文件里理解"wiki 原文错在哪、现在的写法为什么对" - 验收标准:能用一句话向同组同学解释清楚,不能只念代码
- 基础知识 · 参考:
docs/ERRATA.md
- 目标:从
- 任务卡 3(选做)· 版本探针
- 目标:用
tools/std_probe.py验证一个标准版本差异点(如三目运算符可否作左值) - 验收标准:跑出至少一个"该标准报错、另一个标准不报错"的对比结果,对照
docs/VERSION_NOTES.md§2 - 基础知识 · 参考:
tools/std_probe.py;docs/VERSION_NOTES.md
- 目标:用
当日产出验证:cmake --build build --target all (Part1) 全绿;每组提交一句话
分工说明 + 至少 1 条 ERRATA 坑点讲解。
Day 2 — Qt 开发环境 / 信号槽 / 基础控件 / 布局与 QSS
模块 A:项目结构 / 第一个程序 / 信号槽
讲(35min):
| 知识点 | 文件 |
|---|---|
最小 Qt 程序结构(QApplication + exec()) |
p03/ch02/minimal_qt_app.cpp |
| 控件创建与显示 | p03/ch03/button_creation.cpp |
| 内置 / 自定义 / lambda 信号槽 | p03/ch04/builtin_signal_slot.cpp、custom_signal_slot.cpp、lambda_signal_slot.cpp |
练(95min):
- 任务卡 1 · 跑通最小程序
- 目标:编译运行
minimal_qt_app与button_creation - 验收标准:
QT_QPA_PLATFORM=offscreen tools/run_qt.sh minimal_qt_app与button_creation均退出码为 0,无崩溃 - 基础知识 · 参考:
p03/ch02/minimal_qt_app.cpp;p03/ch03/button_creation.cpp
- 目标:编译运行
- 任务卡 2 · 自定义信号槽改文本
- 目标:给一个按钮连接自定义信号槽,点击后改变一个
QLabel的文本内容 - 验收标准:编译通过;离屏或有 X 环境下点击/模拟点击后
QLabel文本确实改变;用connect语法而非直接函数调用 - 基础知识 · 参考:
p03/ch04/custom_signal_slot.cpp(主参考)、lambda_signal_slot.cpp(lambda 槽写法对比)
- 目标:给一个按钮连接自定义信号槽,点击后改变一个
- 任务卡 3(选做)· 重载信号消歧义
- 目标:仿
builtin_signal_slot.cpp,给一个类定义两个同名不同参的信号,用QOverload消歧义连接 - 验收标准:两个重载信号都能各自触发对应的槽
- 基础知识 · 参考:
p03/ch04/builtin_signal_slot.cpp
- 目标:仿
模块 B:常用控件 / 布局管理 / QSS 界面美化 → 计算器案例
讲(35min):
| 知识点 | 文件 |
|---|---|
| 图片/文本标签控件 | p03/ch08/label_pixmap.cpp、label_text_html.cpp |
自定义控件与布局(QHBoxLayout) |
p03/ch08/custom_widget.cpp |
| QSS 界面美化(教学补充) | docs/teaching/examples/qss_styling/qt_qss_styling.cpp |
练(95min,计算器案例——练习任务,非预建方案):
- 任务卡 1 · 计算器雏形
- 目标:组合
button_creation.cpp(多个数字/运算符按钮)+custom_signal_slot.cpp(点击信号槽)+custom_widget.cpp(QGridLayout或QVBoxLayout排布按钮),做出一个能加减乘除的最小计算器 - 验收标准:至少支持两个数 + 一种运算符的计算并在
QLabel/QLineEdit上正确显示结果;界面不重叠、按钮可点击 - 基础知识 · 参考:
p03/ch03/button_creation.cpp、p03/ch04/custom_signal_slot.cpp、p03/ch08/custom_widget.cpp
- 目标:组合
- 任务卡 2 · 用 QSS 美化计算器
- 目标:给任务卡 1 的计算器套一份 QSS 样式(数字键/运算键/等号键区分颜色)
- 验收标准:至少 2 类按钮有不同的
background-color;至少 1 个按钮有:hover或:pressed效果 - 基础知识 · 参考:
docs/teaching/examples/qss_styling/qt_qss_styling.cpp、README
当日产出验证:现场演示计算器(QT_QPA_PLATFORM=offscreen tools/run_qt.sh <target>
或有 X 环境直接运行),至少完成一次正确运算 + QSS 美化。
Day 3 — 高级控件与 Model/View / 事件机制 / 文件 IO 与 JSON
模块 A:Model/View 架构 / 事件机制
讲(35min):
| 知识点 | 文件 |
|---|---|
| Model/View 模型视图架构(教学补充) | docs/teaching/examples/model_view/qt_model_view_basics.cpp |
| 事件循环机制(复用 Day2 概念) | p03/ch02/minimal_qt_app.cpp 的 app.exec() |
| 自定义事件处理 / 事件过滤器 | p03/ch09/event_override_customwidget.cpp、event_filter_mainwindow.cpp |
| 鼠标事件 | p03/ch09/mouse_event.cpp |
练(95min):
- 任务卡 1 · Model/View 换视图
- 目标:把
qt_model_view_basics.cpp里的QListView换成QTableView,模型代码不改 - 验收标准:编译通过,界面正常展示同一份数据,证明"同一个模型可以喂给不同视图"
- 基础知识 · 参考:
docs/teaching/examples/model_view/qt_model_view_basics.cpp、README
- 目标:把
- 任务卡 2 · 事件过滤器实操
- 目标:仿
event_filter_mainwindow.cpp,给一个控件装事件过滤器,拦截鼠标按下事件并打印坐标 - 验收标准:点击控件后终端/调试输出能看到坐标信息
- 基础知识 · 参考:
p03/ch09/event_filter_mainwindow.cpp、mouse_event.cpp
- 目标:仿
模块 B:文件 IO / JSON 解析 → 本地数据存储案例
讲(35min):
| 知识点 | 文件 |
|---|---|
| 文本文件读写 | p03/ch11/qfile_basic.cpp、qtextstream_io.cpp |
| 结构化二进制读写 | p03/ch11/qdatastream_io.cpp |
| JSON 解析与写入(教学补充) | docs/teaching/examples/json_io/qt_json_parse_write.cpp |
练(95min,本地数据存储案例——练习任务,非预建方案):
- 任务卡 1 · JSON 落盘
- 目标:把
qt_json_parse_write.cpp的 JSON 数据实际写入一个文件(结合qfile_basic.cpp的QFile写法),再读回来解析校验 - 验收标准:程序运行后磁盘上生成一个
.json文件,内容可读;重新运行程序能正确解析出之前写入的数据 - 基础知识 · 参考:
docs/teaching/examples/json_io/qt_json_parse_write.cpp、README、p03/ch11/qfile_basic.cpp
- 目标:把
- 任务卡 2 · 本地数据存储小工具
- 目标:设计一个"学员信息"结构(姓名/成绩/标签),支持增加一条记录并追加保存到 JSON 文件,重启程序后能读出之前保存的全部记录
- 验收标准:至少能存 2 条以上记录并在重启后完整读回;数据字段不丢失
- 基础知识 · 参考:
docs/teaching/examples/json_io/、p03/ch11/qtextstream_io.cpp
当日产出验证:现场演示本地数据存储小工具,验证"写入 → 重启 → 读回"完整闭环。
Day 4 — 2D 图形绘制 / 多线程 / 动画框架与状态机
模块 A:2D 绘图 / 多线程
讲(35min):
| 知识点 | 文件 |
|---|---|
QPainter 基础绘图 |
p03/ch10/qpainter_basic.cpp |
绘图设备(QImage/QPixmap/QPicture) |
p03/ch10/paint_device_qimage.cpp、paint_device_pixmaps.cpp、qpicture_io.cpp |
| QThread 多线程(教学补充) | docs/teaching/examples/qthread_worker/qt_thread_worker.cpp |
练(95min):
- 任务卡 1 · 画一个简单图形界面
- 目标:仿
qpainter_basic.cpp,在paintEvent里画一个组合图形(如棋盘格/仪表盘刻度) - 验收标准:编译通过,离屏或 X 环境下能看到图形正确绘制(可截图验证)
- 基础知识 · 参考:
p03/ch10/qpainter_basic.cpp
- 目标:仿
- 任务卡 2 · 感受多线程不卡界面
- 目标:把
qt_thread_worker.cpp里的耗时计算换成一个更长的循环或QThread::msleep,观察主线程/事件循环没有被卡住 - 验收标准:能说清楚"如果把这段计算直接放主线程会发生什么"(界面无响应),并解释
moveToThread起的作用 - 基础知识 · 参考:
docs/teaching/examples/qthread_worker/qt_thread_worker.cpp、README
- 目标:把
模块 B:动画框架 / 状态机 → 交互式小游戏案例
讲(35min):
| 知识点 | 文件 |
|---|---|
| QPropertyAnimation 动画(教学补充) | docs/teaching/examples/property_animation/qt_property_animation.cpp |
| QStateMachine 状态机(教学补充) | docs/teaching/examples/state_machine/qt_state_machine.cpp |
练(95min,交互式小游戏案例——练习任务,选做,非预建方案):
- 任务卡 1 · 动画 + 状态机组合
- 目标:把
qt_property_animation.cpp的动画和qt_state_machine.cpp的状态切换组合到同一个窗口——例如按钮在"红灯"状态时禁止移动,"绿灯"状态时点击才触发动画 - 验收标准:状态切换正确(红灯不触发动画,绿灯触发动画);动画播放完整不报错
- 基础知识 · 参考:
docs/teaching/examples/property_animation/、docs/teaching/examples/state_machine/
- 目标:把
- 任务卡 2(选做)· 简易反应力小游戏
- 目标:结合任务卡 1 + 鼠标事件(Day3
mouse_event.cpp)+ 多线程计时(Day4qt_thread_worker.cpp),做一个"状态变化后限时点击"的最小交互游戏 - 验收标准:游戏至少有"开始→进行中→结束"三个可辨识状态,计时或计分逻辑不崩溃
- 基础知识 · 参考:上述三个教学补充示例 +
p03/ch09/mouse_event.cpp
- 目标:结合任务卡 1 + 鼠标事件(Day3
当日产出验证:分组演示动画+状态机组合小工具(任务卡 2 选做,量力而行)。
Day 5 — 团队协同开发 / 综合案例复盘 / OpenCV(可选自学)
模块 A:团队协同开发(概念讲解)
讲(35min):
| 内容 | 素材 |
|---|---|
| 项目开发过程管理全景(JIRA + Git + WIKI + 钉钉直播) | docs/images/training_service_flow.png |
| 质量保证体系(四平台一标准) | docs/images/quality_four_platforms.png |
| 标准化考核标准 | docs/images/assessment_standard.png |
| 代码团队协同开发实操建议 | docs/TRAINING_PLAN_2026.md 「七、质量保证 (二) Git」 |
讨论(95min):
- 任务卡 1 · 分工复盘
- 目标:结合考核标准图(项目管理评估/项目技术评估/职业素养评估三大块),对照 Day1 任务卡 1 定下的分工,检查执行情况
- 验收标准:每组能说出至少 1 项做得好的、1 项需要改进的
- 基础知识 · 参考:
docs/images/assessment_standard.png
模块 B:综合案例复盘 + OpenCV/AI(可选,自学指针)
讲(35min):
| 内容 | 说明 |
|---|---|
| Day2–4 案例回顾 | 请 1–2 组现场展示计算器/本地存储/动画状态机小游戏 |
| OpenCV 与 AI 机器学习(可选,自学指针,无配套代码) | 方案书原文标注"可选择";如学员感兴趣,自学方向为 cv::CascadeClassifier 人脸检测入门,OpenCV 官方教程(需联网,选读) |
练(95min,综合演练):
- 任务卡 1 · 三选一深化
- 目标:从计算器 / 本地数据存储 / 动画状态机小游戏中选一个继续深化(加一个新功能)
- 验收标准:现场演示新增功能正常工作,编译无报错
- 基础知识 · 参考:回顾 Day2–4 对应的教学补充示例与 README
当日产出验证:每组现场演示深化后的案例,教师按考核标准图三大块给出反馈, 为 Day6–10 的正式项目实作分组定方向。
4. 验证与考核方式
- 每天结束前 10 分钟:学员提交当天任务卡的产出文件,用
cmake --build build验证 (Qt 相关目标需先-DBUILD_QT_PART=ON -DCMAKE_PREFIX_PATH=$PWD/.qt514/5.14.2/gcc_64)。 - Day5 结束:三选一深化案例的现场演示,作为 Day1–5 阶段的考核点,同时对齐 方案书「标准化的考核标准」三大评估维度(项目管理/项目技术/职业素养)。
- 教师侧参考答案:仓库已有的
p03/文件和docs/teaching/examples/里的教学 补充示例都是可运行的正确版本,可直接用作评分参照;docs/ERRATA*.md记录了 每一处 wiki 原文修正,可用于讲解"错在哪、对在哪"。
5. 材料与播放方式
- 大纲:本文件
docs/teaching/OUTLINE.md。 - 交互幻灯片:
docs/teaching/slides/day1.html…day5.html,index.html为入口页。 - 教学补充示例:
docs/teaching/examples/,6 个最小可运行 Qt 程序 + README, 构建方式见根CMakeLists.txt里docs/teaching/examples一节;运行方式与p03/里的示例一致:QT_QPA_PLATFORM=offscreen tools/run_qt.sh <target>。 - 技术方案:reveal.js 5.2.1(仅
dist/核心 +plugin/highlight)已 vendor 进docs/teaching/slides/reveal/,零 CDN 依赖,断网教室也能播放。任务卡里的<span class="ext-ref">标注的官方文档/外部教程是选读项,需要联网才能 打开,不影响幻灯片本身离线播放。 - 播放方式(代码链接用相对路径指向仓库源文件,需要 HTTP 而非
file://才能正常跳转):cd /home/charles/workspaces/qt-course python3 -m http.server 8000 # 浏览器打开 http://localhost:8000/docs/teaching/slides/index.html - 幻灯片内所有「文件」链接均为相对本仓库路径的可点击链接,点开后由浏览器直接展示 源码(配合上面的 http.server);教师也可直接在编辑器里打开同一路径带学员精读。