Day4 教学示例补三个:QDialog 综合 / QLineEdit 小眼睛 / 文件 IO(+顶层构建注册)

- qdialog_showcase:wiki「6 对话框 QDialog」6.2–6.5 综合演示。含两套实现:
  · Designer 表单版(dialog.{h,cpp,ui} + resources.qrc + source.gif,QMovie 播 GIF)
  · 纯代码版(qt_dialog_showcase.cpp,单文件,QWidget 布满按钮逐个演示 QDialog 行为)
- lineedit_eye_toggle:子类化 QLineEdit,paintEvent 自绘小眼睛、mouseEvent 命中切换
  echoMode,并与内置 clear button 动态避让(读 objectName=="clearButton" 子 widget 几何)。
  含独立子目录 CMakeLists.txt 供单独打开(顶层 add_subdirectory 不递归)。
- file_io_demo:QFile/QTextStream/QDataStream/QFileInfo/QDir/QTextCodec/QJson 五主题
  综合示例,每个按钮产出一个文件落到 demo_output/ 便于课堂手动查看。

构建注册:examples/CMakeLists.txt 用 add_teaching_example 注册前两个纯代码示例,
mandelbrot 多源文件单独 add_executable;calculator_mainwindow_qss 加 themes.qrc 与
AUTORCC;all_teaching_examples 依赖列表同步补齐。

附 lineedit_eye_toggle 设计文档(docs/superpowers/specs)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
张宗平
2026-07-09 16:51:09 +08:00
parent 993aa30a1c
commit 01b264fe97
16 changed files with 1694 additions and 3 deletions
@@ -0,0 +1,78 @@
# QDialog 教学综合示例(qt_dialog_showcase
参考川大 wiki「6 对话框 QDialog」(pageId 183664881) 的 **6.26.5**,形态为一个
**QWidget 布满 pushbutton**:每个按钮触发一种 `QDialog` 行为。纯代码(无 `.ui`),主类不
定义信号槽,全部用 lambda 连接 `QPushButton::clicked`
> 仓库 `p03/ch06` 已有零散单行为示例(modal_dialog / modeless_dialog_* / message_box_* /
> file_dialog);本示例是**综合演示**,把页面的全部行为聚到一个窗口对照体验。
## 16 个按钮 ↔ 页面行为
### ① 模态 / 非模态(6.3)
| 按钮 | 行为 | 关键 API / 要点 |
|---|---|---|
| 模态 exec | `QDialog::exec()` | 应用级模态,阻塞整个应用直到关闭 |
| 窗口模态 open | `QDialog::open()` | 窗口级模态,仅阻塞父窗口 |
| 非模态 show | `new QDialog->show()` | 非模态,立即返回;**栈对象会一闪而过**(6.3 的坑) |
| 非模态+删除关闭 | `setAttribute(WA_DeleteOnClose)+show()` | 关闭即 delete,避免无 parent 堆对象泄漏 |
### ② QMessageBox6.4
| 按钮 | 行为 |
|---|---|
| about / aboutQt / critical / information / question / warning | 六个 static 函数 |
| 自定义消息框 | 实例 API`setIcon / setText / setInformativeText / setDetailedText / setStandardButtons / setDefaultButton` + `exec` |
### ③ 标准对话框(6.2 / 6.5
| 按钮 | 行为 |
|---|---|
| 打开文件 | `QFileDialog::getOpenFileName` |
| 保存文件 | `QFileDialog::getSaveFileName` |
| 选颜色 | `QColorDialog::getColor` |
| 选字体 | `QFontDialog::getFont` |
| 输入文字 | `QInputDialog::getText` |
底部 `QLabel` 显示标准对话框 / question / 自定义消息框的返回值。
## 关键教学点
- **exec vs open vs show**:三种模态/非模态实现,对应 6.3。`exec()` 阻塞整个应用;
`open()` 阻塞父窗口;`show()` 不阻塞。
- **栈对象坑(6.3**`QDialog d; d.show();` 在函数返回时 `d` 析构,对话框立即消失 →
必须用堆对象(`new`)。
- **WA_DeleteOnClose6.3**:无 parent 的堆对象靠它在关闭时自动 `delete`,避免内存泄漏。
- **QMessageBox static vs 实例(6.4**staticabout / question / …)调用最简;实例 API
可设详细文本(`setDetailedText` 出现「显示详情...」按钮)与任意按钮组合。
- **标准对话框统一风格(6.2/6.5)**:`QFileDialog / QColorDialog / QFontDialog / QInputDialog`
都是 `get...` static,返回用户选择,`isEmpty()`/`isValid()`/`&ok` 判断是否取消。
## 目录结构
```
qdialog_showcase/
├── qt_dialog_showcase.cpp # DialogShowcase : QWidget(无 Q_OBJECT,纯 lambda+ main
└── README.md # 本文档
```
## 构建与运行(Windows + MinGW 7.3.0 + Qt 5.14.2
> 必须用与 Qt 5.14.2 ABI 匹配的 mingw730_64,不可用 PATH 中更高版本的 g++。
```bash
# 配置(在仓库根)
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
# 构建单目标
cmake --build build_mw --target qt_dialog_showcase
# 运行(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_dialog_showcase.exe
# 离屏自动退出验证(不点按钮,退出码应为 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_dialog_showcase.exe; echo "exit=$?"
```