- 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>
9.4 KiB
Day2–4 课堂练习 + 课后作业(分层设计)
配套
OUTLINE_4DAY.md的任务卡、slides/day2.html…day4.html里的「练/作业」小节。本文给出可直接打印/投屏的作业单:每项作业拆成 基础版(必做,验收线) + 挑战版(选做,见能力发挥) 两层,时间预算按 「基础版 1 小时内可完成、挑战版累计不超过 2 小时」控制,照顾基础不理想的 学员——先保基础版全员过关,挑战版不做不扣分。
分层设计原则
- 基础版是及格线,不是引导线:题面本身已经是当天知识点的最小闭环,做完 基础版=当天目标达成;工程师答疑优先保基础版全员通过。
- 挑战版是同一个程序的自然延伸,不引入新知识点,只要求「更完整/更健壮/ 更贴近真实使用」——强度落在「把已学的东西用得更彻底」,不是提前预习明天内容。
- 验收用现场提问代替翻源码:给几组输入让学生当场演示结果(下表「验收用例」), 比对照代码更能测出是真理解还是照抄。
- 每天的作业首尾相接(计算器 → 计算器 QMainWindow 化 + 美化 → 数据存储工具), 挑战版做不完不影响第二天用基础版继续。
Day2 下午 · 简易计算器
对应任务卡 2(OUTLINE_4DAY.md Day2 下午作业)。教师参考实现:
examples/calculator/(代码布局版)、
examples/calculator_designer/(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:00–12:00)。
参考实现:examples/calculator_mainwindow/
(以 Day2 增强版 calculator_designer_ext/
为起点;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/
(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:00–12:00)。
| 要求 | 时间预算 | |
|---|---|---|
| 基础版(必做,二选一) | ① 给某个控件装 installEventFilter(),鼠标按下时在控制台打印坐标;或 ② 重写 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/ 的直接前身,
教师验收时可参考其数据层设计(不要求学生做到那个完整度)。
| 要求 | 时间预算 | |
|---|---|---|
| 基础版(必做) | 「学员信息」表单(姓名/成绩/标签,3 个 QLineEdit + 「添加」按钮)把记录追加到列表控件(QListWidget/QTableWidget 均可);「保存」按钮把全部记录写成 JSON 文件;重启程序后「读取」按钮能把之前保存的记录读回、字段不丢、顺序不乱(至少 2 条) |
≈1.5h |
| 挑战版(选做) | ① 加「删除选中行」;② 数据文件路径用 QCoreApplication::applicationDirPath() 拼接,不用裸相对路径(当天★坑卡的实操版);③ 读取时文件不存在/JSON 格式损坏要给出友好提示而不是崩溃或静默清空(检查 open() 返回值和 QJsonParseError) |
≤1h |
验收用例:添加 2 条记录 → 保存 → 关闭程序 → 重新打开 → 点「读取」→ 2 条记录 都在、字段值正确;挑战版——把 JSON 文件手动改坏一个字符再读取,程序不崩溃。
给基础不理想同学的提示:先固定用一个写死的文件名(比如 data.json)把
「写入→读回」跑通,再考虑路径是否规范(挑战版①);QJsonDocument::toJson()/
fromJson() 是配对的两端,写的时候用什么结构(数组套对象),读的时候就按同样
结构解析回来,两边字段名要完全一致(区分大小写)。
给工程师/助教的验收操作提示
- 11:00–12:00、16:00–17:00 两个答疑窗口,优先确认基础版验收用例,挑战版 时间不够可以留到当晚或第二天早上补交,不阻塞后续课程进度。
- 每天验收合格线 = 基础版全部用例通过;挑战版按完成比例加分,不设满分门槛。
- 若某学员基础版都吃力,参照各节「给基础不理想同学的提示」拆解成更小步骤,
必要时可对照教师参考实现(
examples/calculator/、examples/calculator_designer/) 逐段讲解,但不要直接给学生抄源码——抄一次治标不治本,下一天同类问题会 重复出现。