- 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>
QMainWindow 教学综合示例(qt_mainwindow_showcase)
覆盖川大 wiki「5 QMainWindow」(pageId 58954529,https://wiki.suncaper.net/display/scu2023/5+QMainWindow)
的 5.1–5.6 全部六大核心组件,形态为极简文本编辑器(QTextEdit 中心部件),
纯组件演示、无文件 I/O。主窗体结构用 Qt Designer(.ui) 设计,应用图标与动作图标
走 资源文件(.qrc)。
仓库已有
p03/ch05/的零散单组件示例(central_widget、dock_widget);本示例是 综合演示,把六者整合到一个QMainWindow程序里,并能交互操控它们。
六大组件 ↔ 代码映射
| wiki | 组件 | 代码位置 | 演示的 API |
|---|---|---|---|
| 5.5 | 中心部件 | mainwindow.ui:centralwidget/textEdit;.cpp:textChanged/cursorPositionChanged → updateStatusBar |
setCentralWidget(QTextEdit) |
| 5.1 | 菜单栏 | .ui:menubar + menuFile/menuView/menuHelp/menuToolBarArea + 12 个 QAction;.cpp:on_action*_triggered/toggled |
menuBar()/addMenu/QAction |
| 5.2 | 工具栏 | .ui:mainToolBar(复用 QAction);.cpp:setMovable/setAllowedAreas/setVisible |
addToolBar/setAllowedAreas/setMovable |
| 5.3 | 状态栏 | .cpp:addPermanentWidget(statusPosLabel)/showMessage |
addWidget/insertWidget/removeWidget(见下) |
| 5.4 | 浮动窗口 | .ui:dockWidget;.cpp:setFloating/setAllowedAreas |
QDockWidget/addDockWidget |
| 5.6 | 资源文件 | mainwindow.qrc + .ui 的 windowIcon + 各 QAction 图标 |
:/icons/*.png |
关键设计点
1. QAction 是菜单项与工具按钮的公共抽象(5.1)
12 个 QAction 在 .ui 的 MainWindow widget 内定义一次,被菜单和工具栏共同引用
(<addaction name="..."/>)——这正是 wiki 强调的「同一动作,加进菜单显示为菜单项、
加进工具栏显示为工具按钮」。例如 actionNew 同时出现在「文件」菜单和主工具栏。
2. 信号槽:on_<objectName>_<signal> 自动连接
槽命名遵循 Qt 约定,由 setupUi() 触发的 QMetaObject::connectSlotsByName 自动连接,
无需手写 connect(KISS)。例如 on_actionToggleDockFloating_triggered() 自动连接
actionToggleDockFloating 的 triggered 信号。
3. 视图菜单 = 「操控」各组件的入口
| 动作 | 行为 | 对应组件/API |
|---|---|---|
| 显示主工具栏 ✓ | mainToolBar->setVisible(checked) |
5.2 |
| 显示状态栏 ✓ | statusBar()->setVisible(checked) |
5.3 |
| 工具栏可移动 ✓ | mainToolBar->setMovable(checked) |
5.2 setMovable |
| 停靠窗口浮动/停靠 | dockWidget->setFloating(!isFloating()) |
5.4 setFloating |
| 显示浮动窗口 | dockWidget->show() |
5.4 重新显示(被 X 关闭后找回) |
| 关闭浮动窗口 | dockWidget->hide() |
5.4 直接隐藏 |
| 工具栏停靠区(子菜单 5 项) | mainToolBar->setAllowedAreas(...) |
5.2 setAllowedAreas |
4. 状态栏 API(5.3)
运行时演示 addPermanentWidget(永久「行:列 字数」标签)+ showMessage(动作临时提示)。
其余三 API 的等价用法(教学参考):
// addWidget:在状态栏左侧添加普通部件(非永久,会挤占临时消息区)
statusBar()->addWidget(new QLabel("就绪"));
// insertWidget:在 index 位置插入部件
statusBar()->insertWidget(0, new QLabel("插入"));
// removeWidget:移除某部件
statusBar()->removeWidget(someLabel);
目录结构
mainwindow_showcase/
├── mainwindow.ui # Designer 表单:主窗体结构 + 12 个 QAction
├── mainwindow_showcase.h/.cpp # MainWindow 类(动态行为)
├── main.cpp # QApplication + offscreen 自动退出
├── mainwindow.qrc # 资源清单(5 个图标)
├── gen_icons.py # 图标生成脚本(标准库,无依赖)
├── icons/ # app/new/quit/about/dock.png(gen_icons.py 产物)
└── README.md # 本文档
构建与运行(Windows + MinGW 7.3.0 + Qt 5.14.2)
必须用与 Qt 5.14.2 ABI 匹配的 mingw730_64(
E:/Qt/Qt5.14.2/Tools/mingw730_64), 不可用 PATH 中可能存在的更高版本 g++。
# 1) 生成图标
python docs/teaching/examples/mainwindow_showcase/gen_icons.py
# 2) 配置(在仓库根;本示例随 docs/teaching/examples 一起被顶层 CMakeLists 收录)
cmake -S . -B build_mw -G "MinGW Makefiles" \
-DCMAKE_PREFIX_PATH=E:/Qt/Qt5.14.2/5.14.2/mingw73_64 \
-DCMAKE_CXX_COMPILER=E:/Qt/Qt5.14.2/Tools/mingw730_64/bin/g++.exe \
-DCMAKE_C_COMPILER=E:/Qt/Qt5.14.2/Tools/mingw730_64/bin/gcc.exe
# 3) 构建单目标
cmake --build build_mw --target qt_mainwindow_showcase
# 4) 运行(GUI)
PATH=/e/Qt/Qt5.14.2/5.14.2/mingw73_64/bin:$PATH \
QT_QPA_PLATFORM_PLUGIN_PATH=/e/Qt/Qt5.14.2/5.14.2/mingw73_64/plugins/platforms \
./build_mw/docs/teaching/examples/qt_mainwindow_showcase.exe
# 5) 离屏自动退出验证(退出码应为 0)
QT_QPA_PLATFORM=offscreen \
QT_QPA_PLATFORM_PLUGIN_PATH=/e/Qt/Qt5.14.2/5.14.2/mingw73_64/plugins/platforms \
PATH=/e/Qt/Qt5.14.2/5.14.2/mingw73_64/bin:$PATH \
./build_mw/docs/teaching/examples/qt_mainwindow_showcase.exe; echo "exit=$?"
教学要点小结
- 一个
QMainWindow= 菜单栏(≤1)+ 工具栏(多个)+ 状态栏(1)+ 浮动窗口(多个)+ 中心部件(1)。 QAction是「动作」的抽象,菜单与工具栏共享。- 工具栏/浮动窗口都是可移动的,停靠区域可由
setAllowedAreas限定。 - 资源文件(
.qrc)把图标编译进可执行文件,运行时用:/...引用,无需关心磁盘文件。