Files
scuc-qt-course/docs/teaching/ASSIGNMENTS.md
T
张宗平 05a685c952 Day3 教学示例:增强版计算器接入 + QMainWindow/QSS 两版参考实现
- calculator_designer_ext(Day2 增强版:表达式求值 + 括号,递归下降解析器)接入 cmake
- calculator_mainwindow(Day3 上午):增强版计算器装进 QMainWindow,
  菜单/状态栏/历史停靠窗,纯代码 + 显式 connect,与 mainwindow_showcase 形成坑卡对照
- calculator_mainwindow_qss(Day3 下午):上午版 + QSS 双主题美化(按键分色/伪状态/深浅切换)
- 验证 mainwindow_showcase(QMainWindow 六大组件综合演示,.ui + .qrc)
- OUTLINE_4DAY.md / ASSIGNMENTS.md Day3 衔接增强版起点 + 参考实现指引
- 补提交 Day2 calculator/ 与 calculator_designer/ 参考实现(CMakeLists 已引用)
- 全量构建 28/28,4 目标离屏自测退出码 0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 22:59:05 +08:00

141 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Day2–4 课堂练习 + 课后作业(分层设计)
> 配套 [`OUTLINE_4DAY.md`](OUTLINE_4DAY.md) 的任务卡、`slides/day2.html`…`day4.html`
> 里的「练/作业」小节。本文给出可直接打印/投屏的作业单:每项作业拆成
> **基础版(必做,验收线)** + **挑战版(选做,见能力发挥)** 两层,时间预算按
> 「基础版 1 小时内可完成、挑战版累计不超过 2 小时」控制,照顾基础不理想的
> 学员——**先保基础版全员过关,挑战版不做不扣分**。
## 分层设计原则
1. **基础版是及格线,不是引导线**:题面本身已经是当天知识点的最小闭环,做完
基础版=当天目标达成;工程师答疑优先保基础版全员通过。
2. **挑战版是同一个程序的自然延伸**,不引入新知识点,只要求「更完整/更健壮/
更贴近真实使用」——强度落在「把已学的东西用得更彻底」,不是提前预习明天内容。
3. **验收用现场提问代替翻源码**:给几组输入让学生当场演示结果(下表「验收用例」),
比对照代码更能测出是真理解还是照抄。
4. 每天的作业首尾相接(计算器 → 计算器 QMainWindow 化 + 美化 → 数据存储工具),
挑战版做不完不影响第二天用基础版继续。
---
## Day2 下午 · 简易计算器
对应任务卡 2`OUTLINE_4DAY.md` Day2 下午作业)。教师参考实现:
[`examples/calculator/`](examples/calculator/README.md)(代码布局版)、
[`examples/calculator_designer/`](examples/calculator_designer/README.md)Qt Designer 对照版)。
| | 要求 | 时间预算 |
|---|---|---|
| **基础版(必做)** | 数字键 0–9 + 至少一种运算符(+/-/×/÷ 任选其一)+ 等号,能正确显示两个数的运算结果;界面不重叠、按钮可点击;`connect` 全部用新语法且写在构造函数里 | ≈1h |
| **挑战版(选做)** | 补全四则运算全部支持;小数点;清空键 `C`;退格键 `⌫`;除零不崩溃、显示 `Error` 且下一次输入自动清空;连续按运算符实现链式计算(如 `2+3+4=``9` | 累计 ≤2h |
**验收用例**(现场让学生当场演示,不看代码):
- 基础版:`7 + 3 =``10``9 - 4 =``5`(任选一种运算符即可)
- 挑战版:`6 ÷ 0 =``Error``4.5 + 0.5 =``5`;连续输入 `12` 后按退格 → `1`
`2 + 3 + 4 =``9`
**给基础不理想同学的提示**:卡在"点击没反应"先查 `connect` 有没有漏写、按钮有没有
真的加到布局里;卡在"数字显示不对"先只处理个位数,两位数以上的拼接逻辑
`display->text() + 新数字`)留到基础版跑通个位数运算之后再加。
---
## Day3 上午 · 计算器 QMainWindow 化
对应 `OUTLINE_4DAY.md` Day3 上午课堂练习(11:0012:00)。
参考实现:[`examples/calculator_mainwindow/`](examples/calculator_mainwindow/README.md)
(以 Day2 增强版 [`calculator_designer_ext/`](examples/calculator_designer_ext/README.md)
为起点;`CalculatorDesigner` 是独立 `QWidget``setCentralWidget` 装进 `QMainWindow`
核心求值逻辑不动,仅加 `evaluated` 信号供历史停靠窗订阅)。
| | 要求 | 时间预算 |
|---|---|---|
| **基础版(必做)** | 把 Day2 计算器的键盘 `setCentralWidget` 装进 `QMainWindow`;加菜单栏「帮助→关于」,点击弹出 `QMessageBox::about` 显示一句自我介绍 | ≈40min |
| **挑战版(选做)** | 加一个「历史」停靠窗(`QDockWidget` + `QListWidget`):每次按等号,把这次的算式和结果(如 `7+3=10`)追加成一条历史记录;停靠窗可拖动/浮动/关闭(`QDockWidget` 默认行为,不用额外写代码) | ≤1h |
**验收用例**:点菜单「帮助→关于」能弹框;挑战版——连续算 3 次不同的算式,历史
停靠窗里能看到 3 条记录且内容正确。
**给基础不理想同学的提示**`QMainWindow` 不是 `QWidget` 的替代品,是新建一个
`QMainWindow` 子类,把原来计算器的键盘部分(`QWidget` 或其内容)通过
`setCentralWidget()` 塞进去;菜单点了没反应先检查 `QAction` 是不是忘了 `connect`
(Day3 上午刚讲的坑卡)。挑战版做不完,历史停靠窗留空 `QLabel` 占位即可,
不影响 Day3 下午继续。
---
## Day3 下午 · 计算器美化(QSS)
对应任务卡(`OUTLINE_4DAY.md` Day3 下午作业)。
参考实现:[`examples/calculator_mainwindow_qss/`](examples/calculator_mainwindow_qss/README.md)
(Day3 上午版 + QSS 双主题;与上午版仅 `mainwindow.{h,cpp}` 差异,演示「美化与逻辑正交」)。
| | 要求 | 时间预算 |
|---|---|---|
| **基础版(必做)** | 数字键 / 运算键 / 等号键至少用 3 种不同颜色区分(`setObjectName` + QSS ID 选择器 `#objectName{...}`);整体布局随窗口缩放不重叠、不错位 | ≈1h |
| **挑战版(选做)** | 至少 1 个按钮有 `:hover``:pressed` 视觉反馈;给结果显示框也套样式(圆角边框/字号);额外做一个"深色主题"QSS 字符串,加一个按钮或菜单项用 `setStyleSheet()` 在两套样式间切换 | ≤1h |
**验收用例**:缩放窗口到很小和很大两种尺寸,按钮不重叠不错位;挑战版——点切换
主题按钮,界面颜色整体改变。
**给基础不理想同学的提示**QSS 选择器认的是 `objectName``setObjectName("btnEquals")`
之后才能用 `#btnEquals{...}`),忘设置 `objectName` 是"样式写了但没生效"的头号原因;
先做好 1 种颜色区分再扩展到 3 种,不要一次性套一大段 QSS 上去调不出问题在哪。
---
## Day4 上午 · 事件过滤器 / 自定义绘图
对应 `OUTLINE_4DAY.md` Day4 上午课堂练习(11:0012:00)。
| | 要求 | 时间预算 |
|---|---|---|
| **基础版(必做,二选一)** | ① 给某个控件装 `installEventFilter()`,鼠标按下时在控制台打印坐标;<b>或</b> ② 重写 `paintEvent`,用 `QPainter` 画一个组合图形(棋盘格、简单进度条、或几条交叉线均可) | ≈40min |
| **挑战版(选做,两项整合)** | 在一个自定义 `QWidget` 上:鼠标点击时记录点击坐标(`mousePressEvent` 或事件过滤器都行)到一个 `QVector<QPoint>`,每次点击后 `update()` 触发重绘,`paintEvent` 里把历史上所有点击过的坐标都画出来(比如画小圆点)——点越点越多,图案累积不丢失 | ≤1h |
**验收用例**:基础版①——点击窗口能在控制台看到坐标打印;基础版②——窗口能看到
一个图形;挑战版——连续点击 5 个不同位置,5 个点都保留在画面上(不是只显示
最后一个)。
**给基础不理想同学的提示**:基础版明确「二选一」,不要求两项都做——事件拦截和
自定义绘图是两条独立线索,先吃透一条。忘调用 `update()` 是"画了但界面没刷新"
的头号原因(`paintEvent` 只在 Qt 认为需要重绘时才会被调用,手动改了数据必须
自己触发 `update()`)。
---
## Day4 下午 · 本地数据存储小工具
对应任务卡(`OUTLINE_4DAY.md` Day4 下午作业)。这是 Day5 综合案例
[`examples/student_manager/`](examples/student_manager/README.md) 的直接前身,
教师验收时可参考其数据层设计(不要求学生做到那个完整度)。
| | 要求 | 时间预算 |
|---|---|---|
| **基础版(必做)** | 「学员信息」表单(姓名/成绩/标签,3 个 `QLineEdit` + 「添加」按钮)把记录追加到列表控件(`QListWidget`/`QTableWidget` 均可);「保存」按钮把全部记录写成 JSON 文件;重启程序后「读取」按钮能把之前保存的记录读回、字段不丢、顺序不乱(至少 2 条) | ≈1.5h |
| **挑战版(选做)** | ① 加「删除选中行」;② 数据文件路径用 `QCoreApplication::applicationDirPath()` 拼接,不用裸相对路径(当天★坑卡的实操版);③ 读取时文件不存在/JSON 格式损坏要给出友好提示而不是崩溃或静默清空(检查 `open()` 返回值和 `QJsonParseError` | ≤1h |
**验收用例**:添加 2 条记录 → 保存 → 关闭程序 → 重新打开 → 点「读取」→ 2 条记录
都在、字段值正确;挑战版——把 JSON 文件手动改坏一个字符再读取,程序不崩溃。
**给基础不理想同学的提示**:先固定用一个写死的文件名(比如 `data.json`)把
「写入→读回」跑通,再考虑路径是否规范(挑战版①);`QJsonDocument::toJson()`/
`fromJson()` 是配对的两端,写的时候用什么结构(数组套对象),读的时候就按同样
结构解析回来,两边字段名要完全一致(区分大小写)。
---
## 给工程师/助教的验收操作提示
- 11:0012:00、16:0017:00 两个答疑窗口,**优先确认基础版验收用例**,挑战版
时间不够可以留到当晚或第二天早上补交,不阻塞后续课程进度。
- 每天验收合格线 = 基础版全部用例通过;挑战版按完成比例加分,不设满分门槛。
- 若某学员基础版都吃力,参照各节「给基础不理想同学的提示」拆解成更小步骤,
必要时可对照教师参考实现(`examples/calculator/``examples/calculator_designer/`
逐段讲解,但**不要直接给学生抄源码**——抄一次治标不治本,下一天同类问题会
重复出现。