# Day3 下午参考实现:计算器 QMainWindow + QSS 双主题 > 对应教案 [`OUTLINE_4DAY.md`](../../OUTLINE_4DAY.md) Day3 下午「布局/控件 + QSS 美化」 > + [`ASSIGNMENTS.md`](../../ASSIGNMENTS.md) Day3 下午作业。手工维护,非生成产物。 ## 定位:上午版 + QSS 美化 以 [`../calculator_mainwindow/`](../calculator_mainwindow/README.md)(Day3 上午版)为 起点,**只加 QSS**:按键按功能分色、`:hover`/`:pressed` 视觉反馈、深/浅双主题切换。 菜单/停靠窗/状态栏/计算逻辑与上午版完全一致——**QSS 与逻辑正交**,这正是 Day3 下午 「美化」环节要传达的核心。 ## 与上午版的差异(集中在 `mainwindow.{h,cpp}`) | 改动 | 位置 | 内容 | |---|---|---| | 双主题 QSS 字符串 | `mainwindow.cpp` 顶部 `kLightQss` / `kDarkQss` | 按键分色 + 伪状态 | | 视图菜单「深色主题」 | `buildMenu()` | `checkable` QAction,`toggled` → `onToggleTheme` | | `applyStyle(bool dark)` | `mainwindow.cpp` | `qApp->setStyleSheet(...)` 全局切换 | | 自测加主题断言 | `runSelfTest()` | 验证切换后 `styleSheet()` 含对应主题标识 | `calculatordesigner.{h,cpp}` / `expressionevaluator.{h,cpp}` / `widget.ui` 与上午版 完全一致(自包含复制)。 ## QSS 教学要点(对应 OUTLINE_4DAY.md Day3 下午) 1. **ID 选择器认 objectName**:`QPushButton#btnEquals { ... }` 命中的前提是控件 `setObjectName("btnEquals")`。本例的 objectName 在 `widget.ui` 里已定义 (``),无需再 `setObjectName`—— 这是「样式写了没生效」头号原因(忘设 objectName)的反面教材。 2. **按键分色用功能归类**:数字键(`btn0`–`btn9`,`btnDot`)浅蓝、运算键 (`btnPlus/Minus/Mul/Div`)橙、等号(`btnEquals`)绿、括号灰、清空/退格红—— 用 ID 选择器分组,比给每个按钮单独写样式更易维护。 3. **伪状态**:`:hover` / `:pressed` 不用手写鼠标事件就能做交互反馈。 4. **`qApp->setStyleSheet` 全局 vs `widget->setStyleSheet` 局部**:本例用全局, 一次切换全部生效。坑卡:全局样式会被 widget 级样式覆盖,混用易级联失控 (OUTLINE_4DAY.md Day3 下午「QSS 级联失控」卡)。 5. **主题切换不碰逻辑**:`applyStyle` 只改 `styleSheet`,不动任何业务代码—— QSS 与逻辑正交的可维护性演示。 ## 构建与运行 ```bash cmake --build build --target qt_calculator_mainwindow_qss # 离屏自测(计算用例 + 主题切换改变 styleSheet 的断言,退出码 0 即全过) PATH=E:/Qt/Qt5.14.2/5.14.2/mingw73_64/bin:$PATH \ QT_QPA_PLATFORM=offscreen \ ./build/docs/teaching/examples/qt_calculator_mainwindow_qss.exe; echo "exit=$?" # 有 GUI 环境:勾选「视图→深色主题」看整体配色切换 ./build/docs/teaching/examples/qt_calculator_mainwindow_qss.exe ``` ## 验收对照(ASSIGNMENTS.md Day3 下午) - **基础版**:数字/运算/等号 3 色区分 ✓(本例 5 色,含括号/清空退格) - **基础版**:布局随窗口缩放不重叠 ✓(`QGridLayout` + `QMainWindow` 区域协议) - **挑战版**:`:hover`/`:pressed` ✓ - **挑战版**:结果显示框套样式 ✓(`display`/`expressionEdit` 米黄背景 + 圆角) - **挑战版**:深/浅双主题切换 ✓(视图菜单「深色主题」)