Files
scuc-qt-course/docs/teaching/examples/mainwindow_showcase
张宗平 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
..

QMainWindow 教学综合示例(qt_mainwindow_showcase

覆盖川大 wiki「5 QMainWindow」(pageId 58954529https://wiki.suncaper.net/display/scu2023/5+QMainWindow) 的 5.15.6 全部六大核心组件,形态为极简文本编辑器QTextEdit 中心部件), 纯组件演示、无文件 I/O。主窗体结构用 Qt Designer.ui 设计,应用图标与动作图标 走 资源文件(.qrc

仓库已有 p03/ch05/ 的零散单组件示例(central_widget、dock_widget);本示例是 综合演示,把六者整合到一个 QMainWindow 程序里,并能交互操控它们。

六大组件 ↔ 代码映射

wiki 组件 代码位置 演示的 API
5.5 中心部件 mainwindow.uicentralwidget/textEdit.cpptextChanged/cursorPositionChanged → updateStatusBar setCentralWidget(QTextEdit)
5.1 菜单栏 .uimenubar + menuFile/menuView/menuHelp/menuToolBarArea + 12 个 QAction.cppon_action*_triggered/toggled menuBar()/addMenu/QAction
5.2 工具栏 .uimainToolBar(复用 QAction);.cppsetMovable/setAllowedAreas/setVisible addToolBar/setAllowedAreas/setMovable
5.3 状态栏 .cppaddPermanentWidget(statusPosLabel)/showMessage addWidget/insertWidget/removeWidget(见下)
5.4 浮动窗口 .uidockWidget.cppsetFloating/setAllowedAreas QDockWidget/addDockWidget
5.6 资源文件 mainwindow.qrc + .uiwindowIcon + 各 QAction 图标 :/icons/*.png

关键设计点

1. QAction 是菜单项与工具按钮的公共抽象(5.1)

12 个 QAction.uiMainWindow widget 内定义一次,被菜单和工具栏共同引用 <addaction name="..."/>)——这正是 wiki 强调的「同一动作,加进菜单显示为菜单项、 加进工具栏显示为工具按钮」。例如 actionNew 同时出现在「文件」菜单和主工具栏。

2. 信号槽:on_<objectName>_<signal> 自动连接

槽命名遵循 Qt 约定,由 setupUi() 触发的 QMetaObject::connectSlotsByName 自动连接 无需手写 connectKISS)。例如 on_actionToggleDockFloating_triggered() 自动连接 actionToggleDockFloatingtriggered 信号。

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. 状态栏 API5.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.pnggen_icons.py 产物)
└── README.md                  # 本文档

构建与运行(Windows + MinGW 7.3.0 + Qt 5.14.2

必须用与 Qt 5.14.2 ABI 匹配的 mingw730_64E:/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)把图标编译进可执行文件,运行时用 :/... 引用,无需关心磁盘文件。