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

简易计算器 —— Qt Designer 表单对照版

对应教案 OUTLINE_4DAY.md Day2 下午「项目案例:简易 计算器」。与 ../calculator/(纯代码 QGridLayout 版)对照阅读:界面搭建方式换了,业务逻辑一字不差——onDigit/onOperator/ onEquals/onClear/onBackspace/compute 全部照搬。手工维护,非生成产物。

与代码版的唯一区别:界面从哪来

代码版 qt_calculator.cpp Designer 版 qt_calculator_designer.cpp
控件树+布局 buildKeypad() 手写 new QPushButton + QGridLayout::addWidget calculator_designer.uiDesigner 表单 XML+ uic 编译期生成 ui_calculator_designer.h + setupUi(this) 一次建好
找控件 局部变量/成员指针 ui->btn7ui->display ……(objectName 对应成员名)
构建开关 AUTOMOC ON AUTOMOC ON + AUTOUIC ONCMake 自动跑 uic
业务逻辑 状态机 完全相同

★ 新增知识点:Designer 表单的「自动连接」

ui->setupUi(this) 内部会调用 QMetaObject::connectSlotsByName(this):只要 类里有名为 on_<objectName>_<signal>() 的槽(比如 on_btnClear_clicked()), Qt 会自动把表单里 objectNamebtnClear 的控件的 clicked() 信号连上去, 不需要手写 connect()。这是信号槽的第三种写法(前两种见 ../calculator/)。

本示例故意不用这个自动连接,全部改成显式 connect()——原因是当天的坑卡:

  • 坑:表单里把按钮 objectNamebtnClear 改成 btnReseton_btnClear_clicked() 这个槽不报编译错误、不报运行时错误,只是从此再也不会被调用——connectSlotsByName 找不到匹配的 objectName 时只是静默跳过。这是「静默失败」坑点家族的第三个成员 (前两个是旧 SIGNAL()/SLOT() 字符串语法、重复 connect)。
  • 结论:显式 connect() 虽然多写几行,但改名/删控件时编译器/IDE 能帮你追踪引用, 排查成本远低于依赖命名约定的隐式连接。项目里推荐显式 connecton_xxx_yyy() 自动连接更适合 Qt Designer 快速原型阶段。

验证方式(自测模式)

QT_QPA_PLATFORM=offscreen tools/run_qt.sh qt_calculator_designer
# 自测用例与 ../calculator/ 完全一致:「7+3=10」「6÷0=Error」「4.5+0.5=5」
# 「12 退格→1」「2+3+4=9(链式运算)」,全部通过退出码 0
tools/run_qt.sh qt_calculator_designer    # 有 X 环境:完整交互

课堂讲解建议

  1. 先展示 .ui 文件本身是纯 XML<widget class="QPushButton" name="btn7">…)—— Qt Designer 只是这份 XML 的图形化编辑器,不是什么黑魔法;
  2. 对照 ../calculator/qt_calculator.cppbuildKeypad(),逐行说明 uic 把这份 XML 翻译成了等价的 C++ 建控件代码(build/ 里能翻出真实生成的 ui_calculator_designer.h 验证);
  3. 演示自动连接的坑:把 .ui 里某个按钮的 name 改掉,重新构建,点击按钮 没反应——现场复现「改名静默失效」;
  4. 讨论:两种方式怎么选?—— 快速原型/美术同学调界面用 Designer 更直观; 逻辑复杂、控件数量随数据动态变化(比如 Day5 的表格行)就必须手写代码搭建, .ui 表单描述不了「运行时循环创建 N 个控件」。

参考

  • 代码布局对照版:../calculator/
  • Qt 官方 Widgets 表单机制:uicUser Interface Compiler+ QMetaObject::connectSlotsByName