Skip to content

Commit f8349b0

Browse files
Merge pull request #11 from Awesome-Embedded-Learning-Studio/style/d3-tutorial-sweep
style(tutorial): D3 全库快批——死链修复 + 禁用语清理
1 parent cce369c commit f8349b0

56 files changed

Lines changed: 730 additions & 54 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

todo/instance-library.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
6. industrial 链接 widget 库 .so 复用(speed-meter/circle-progress/line-chart 先落地)
2222

2323
### widget 栏(13·每族代表·自绘递进链)
24-
路径 `widget/<家族>/<控件名>/`。①status-led✅中等档标杆(颜色过渡+呼吸+Q_PROPERTY全+双文档pilot待验格式) ②toggle-switch ③circle-progress ④speed-meter ⑤range-slider ⑥line-chart(纯QPainter) ⑦editable-table ⑧checkbox-tree ⑨checkbox-list ⑩log-viewer ⑪password-edit ⑫ip-edit(P1) ⑬fade-animation(P1)。未覆盖9族首波不碰:calendar/datetime/opengl/specialized/network-widget/data-display/multimedia/map/print。
24+
路径 `widget/<家族>/<控件名>/`。①status-led✅中等档标杆(颜色过渡+呼吸+Q_PROPERTY全+双文档pilot待验格式) ②toggle-switch✅(2026-06-16,滑动动画+拖动/点击+Q_PROPERTY配色+双文档) ③circle-progress ④speed-meter ⑤range-slider ⑥line-chart(纯QPainter) ⑦editable-table ⑧checkbox-tree ⑨checkbox-list ⑩log-viewer ⑪password-edit ⑫ip-edit(P1) ⑬fade-animation(P1)。未覆盖9族首波不碰:calendar/datetime/opengl/specialized/network-widget/data-display/multimedia/map/print。
2525

2626
### app 栏(7旗舰+1拉伸·撑「真库不是片段」)
2727
路径 `app/<类目>/<应用名>/`。image-viewer★5 / sqlite-browser★5 / json-editor★4 / network-tool★4-5 / cpu-memory-monitor★4 / serial-tool★4-5(补入·嵌入式最高频) / tetris★4-5 / ~~audio-visualizer~~(拉伸·须先做模拟数据发生器)。
@@ -42,7 +42,7 @@
4242
> **[格式 gate]** ✅ status-led 已产 Full 导览 + Handbook(入口+01/02/03+troubleshooting)两套样板(2026-06-14,落 `tutorial/engineering/instances/widget/status-led/`)→ 待作者验格式放量后续
4343
4444
①✅已完成:status-led 基建化简(降C++17+重命名+STATIC库) + 深度改造(中等档:颜色过渡 QPropertyAnimation + 呼吸 QVariantAnimation + Q_PROPERTY 全 + minimumSizeHint) + 双文档 pilot(成品导览 + 手搓手册 5 文件) → 作者验过格式再放量
45-
撑场批:status-led→toggle→circle→speed-meter→line-chart + image-viewer/sqlite-browser/serial-tool
45+
✅toggle-switch 已落(2026-06-16,代码+构建门+冒烟+Full+Handbook双文档) → 撑场批续:circle→speed-meter→line-chart + image-viewer/sqlite-browser/serial-tool
4646
③覆盖批:password/ip/range-slider/editable-table/checkbox-tree/list/log-viewer/fade + json-editor/network-tool/cpu-mem
4747
④model reference:undo-redo-framework 1个→定范式→其余17放量
4848
⑤收尾:tetris;audio-visualizer(须先模拟数据发生器)

tutorial/advanced/03-qtwidgets/11-qwidget-base-advanced.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void paintEvent(QPaintEvent*) override
4949

5050
入门篇我们提到了 `Qt::FramelessWindowHint` 去掉标题栏和边框。但去掉标题栏的代价是:窗口不能拖动了。这在实际项目中是个必须解决的问题。
5151

52-
拖动的实现思路很直接:在 mousePressEvent 中记录鼠标按下时的全局坐标和窗口位置,然后在 mouseMoveEvent 中计算鼠标移动的偏移量,用 move() 更新窗口位置。需要注意的是,mouseMoveEvent 默认只在鼠标按键按住时触发(如果没有开启 mouseTracking),所以不需要额外判断按键状态。
52+
拖动的实现思路很直接:在 mousePressEvent 中记录鼠标按下时的全局坐标和窗口位置,然后在 mouseMoveEvent 中计算鼠标移动的偏移量,用 move() 更新窗口位置。mouseMoveEvent 默认只在鼠标按键按住时触发(如果没有开启 mouseTracking),所以不需要额外判断按键状态。
5353

5454
```cpp
5555
void mousePressEvent(QMouseEvent* event) override
@@ -72,7 +72,7 @@ void mouseMoveEvent(QMouseEvent* event) override
7272
7373
这里用 `globalPosition().toPoint()` 而不是 `pos()`,因为我们需要的是鼠标在屏幕上的绝对坐标,而 `pos()` 返回的是相对于控件的坐标。`frameGeometry().topLeft()` 是窗口(含边框)左上角的屏幕坐标——虽然无边框窗口没有可见边框,但 frameGeometry 和 geometry 在无边框窗口上是相等的,所以用哪个都行。减去这个偏移是为了保持鼠标点击位置和窗口左上角的相对距离不变,否则窗口会"跳"到鼠标位置。
7474
75-
接下来还有一个进阶技巧:`Qt::WA_TransparentForMouseEvents`。这个属性让鼠标事件穿透控件,直接传递给它下面的控件。这在做覆盖层(overlay)时非常有用——比如你有一个半透明的信息提示浮在主界面上方,但又不希望它拦截鼠标点击。设置 `setAttribute(Qt::WA_TransparentForMouseEvents)` 后,所有鼠标事件都会穿透这个控件,仿佛它不存在一样。需要注意的是,这个属性只对顶级窗口和有 parent 的子控件有效,而且它不影响键盘事件。
75+
接下来还有一个进阶技巧:`Qt::WA_TransparentForMouseEvents`。这个属性让鼠标事件穿透控件,直接传递给它下面的控件。这在做覆盖层(overlay)时非常有用——比如你有一个半透明的信息提示浮在主界面上方,但又不希望它拦截鼠标点击。设置 `setAttribute(Qt::WA_TransparentForMouseEvents)` 后,所有鼠标事件都会穿透这个控件,仿佛它不存在一样。这个属性只对顶级窗口和有 parent 的子控件有效,而且它不影响键盘事件。
7676
7777
### 3.3 setAttribute 的性能影响——频繁切换属性的开销
7878

tutorial/advanced/03-qtwidgets/12-qabstractbutton-base-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ QAbstractButton 内部维护了两个独立的状态维度:`checked`(bool)
2727

2828
`down` 状态还有一个不太显眼的行为:autoRepeat。当 autoRepeat 开启时,QAbstractButton 会在 `down` 为 true 的期间启动一个内部定时器,按照 autoRepeatDelay 和 autoRepeatInterval 的参数持续触发 clicked()。这个定时器的生命周期完全绑定在 `down` 上——用户松开鼠标时 `down` 变为 false,定时器立刻停止。所以如果你在 mouseReleaseEvent 里拦截了事件但忘了调基类,autoRepeat 也会跟着停不下来,因为 `down` 永远不会被清零。
2929

30-
对于三态按钮(tristate),状态维度从 bool 升级为 `Qt::CheckState` 枚举,包含 `Unchecked``PartiallyChecked``Checked` 三个值。三态切换的循环路径是 `Unchecked -> PartiallyChecked -> Checked -> Unchecked`,但这个循环只在用户点击时生效。程序化调用 `setCheckState()` 可以直接跳到任意状态,不受循环路径限制。需要注意的是,QAbstractButton 层面并没有 tristate 的概念——三态是 QCheckBox 在 QAbstractButton 的 checked bool 之上又加了一层包装。QCheckBox 内部维护了一个 `Qt::CheckState` 类型的成员变量,当 tristate 关闭时它只使用 Unchecked 和 Checked 两个值;开启后才允许 PartiallyChecked 出现。这就是为什么 setTristate(true) 必须显式调用——因为 QAbstractButton 的 checked 本身只有 true/false,没有第三态的位置。
30+
对于三态按钮(tristate),状态维度从 bool 升级为 `Qt::CheckState` 枚举,包含 `Unchecked``PartiallyChecked``Checked` 三个值。三态切换的循环路径是 `Unchecked -> PartiallyChecked -> Checked -> Unchecked`,但这个循环只在用户点击时生效。程序化调用 `setCheckState()` 可以直接跳到任意状态,不受循环路径限制。QAbstractButton 层面并没有 tristate 的概念——三态是 QCheckBox 在 QAbstractButton 的 checked bool 之上又加了一层包装。QCheckBox 内部维护了一个 `Qt::CheckState` 类型的成员变量,当 tristate 关闭时它只使用 Unchecked 和 Checked 两个值;开启后才允许 PartiallyChecked 出现。这就是为什么 setTristate(true) 必须显式调用——因为 QAbstractButton 的 checked 本身只有 true/false,没有第三态的位置。
3131

3232
### 3.2 QStyleOptionButton——按钮绘制的数据包
3333

tutorial/advanced/03-qtwidgets/40-qtabbar-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ QTabBar 还有一个相关属性 elideMode,用来控制标签文字被截断
143143
tabBar->setElideMode(Qt::ElideRight); // 超长标签文字右侧显示"..."
144144
```
145145

146-
需要注意的是,关闭 usesScrollButtons 后用户可能不知道还有更多标签——因为没有可见的滚动提示。如果你的标签栏可能会容纳大量标签(比如浏览器式应用),建议保持 usesScrollButtons 为 true,或者用自定义的按钮来提供更明显的滚动提示。
146+
关闭 usesScrollButtons 后用户可能不知道还有更多标签——因为没有可见的滚动提示。如果你的标签栏可能会容纳大量标签(比如浏览器式应用),建议保持 usesScrollButtons 为 true,或者用自定义的按钮来提供更明显的滚动提示。
147147

148148
## 4. 踩坑预防
149149

tutorial/advanced/03-qtwidgets/58-qstatusbar-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ movie->stop();
116116
sync_label->setText("已同步");
117117
```
118118

119-
最后说自定义 Widget。如果你需要一个状态栏控件同时显示多种信息——比如一个网络状态指示器包含一个颜色圆点和文字——可以继承 QWidget 自己画。QStatusBar 对嵌入的控件没有任何类型限制,只要它是 QWidget 的子类就行。唯一需要注意的是控件的高度:QStatusBar 会根据内部所有控件的最大 sizeHint().height() 来决定自身高度,如果你的自定义控件 sizeHint 返回了一个很大的值,状态栏就会被撑高。
119+
最后说自定义 Widget。如果你需要一个状态栏控件同时显示多种信息——比如一个网络状态指示器包含一个颜色圆点和文字——可以继承 QWidget 自己画。QStatusBar 对嵌入的控件没有任何类型限制,只要它是 QWidget 的子类就行。唯一要留意的是控件的高度:QStatusBar 会根据内部所有控件的最大 sizeHint().height() 来决定自身高度,如果你的自定义控件 sizeHint 返回了一个很大的值,状态栏就会被撑高。
120120

121121
### 3.4 setSizeGripEnabled 与状态栏高度控制
122122

tutorial/advanced/03-qtwidgets/66-qfiledialog-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ dlg->setSidebarUrls({
8383
});
8484
```
8585

86-
自定义侧边栏 URL 是实例化方式的一个实用功能。你可以把项目常用目录加到侧边栏里,这样用户不用每次都从根目录一层层点进去。setSidebarUrls 接受一个 QUrl 列表,每个 URL 会在侧边栏显示为一个快捷按钮。需要注意的是这个功能只在非原生对话框中有效——因为原生对话框的侧边栏由系统控制。
86+
自定义侧边栏 URL 是实例化方式的一个实用功能。你可以把项目常用目录加到侧边栏里,这样用户不用每次都从根目录一层层点进去。setSidebarUrls 接受一个 QUrl 列表,每个 URL 会在侧边栏显示为一个快捷按钮。这个功能只在非原生对话框中有效——因为原生对话框的侧边栏由系统控制。
8787

8888
### 3.4 在非原生对话框中嵌入自定义预览 widget
8989

tutorial/advanced/05-other-modules/24-qttexttospeech-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ void ssml_examples(QTextToSpeech* tts)
148148
149149
`<say-as>` 标签非常有用——它能告诉 TTS 引擎如何解读特定文本。比如电话号码 `138-0013-8000`,不加标记的话引擎可能把它当作普通数字来读;加了 `interpret-as="telephone"` 后引擎会逐位读出每个数字。
150150
151-
需要注意的是,不是所有 TTS 引擎都完整支持 SSML。Windows SAPI 对 SSML 的支持比较好,Linux speech-dispatcher 的 SSML 支持则取决于后端引擎(espeak-ng 支持基本的 SSML,但某些高级标签可能被忽略)。如果你的应用依赖 SSML 的特定功能,需要在不同平台上测试兼容性。
151+
不是所有 TTS 引擎都完整支持 SSML。Windows SAPI 对 SSML 的支持比较好,Linux speech-dispatcher 的 SSML 支持则取决于后端引擎(espeak-ng 支持基本的 SSML,但某些高级标签可能被忽略)。如果你的应用依赖 SSML 的特定功能,需要在不同平台上测试兼容性。
152152
153153
### 3.3 异步状态追踪——synthesize 信号
154154

tutorial/advanced/06-qml/06-qml-model-view-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ ListView {
9696

9797
`section.criteria` 有两个值:`ViewSection.FullString`(精确匹配整个字符串)和 `ViewSection.FirstCharacter`(只取第一个字符来分组)。后者特别适合按首字母分组展示联系人列表的场景——你不需要在模型中额外加一个「首字母」字段,直接用 `section.criteria: ViewSection.FirstCharacter` 就行。
9898

99-
需要注意的是 section 是基于**连续相同值**来分组的,不是全局去重。如果你的模型数据是 `[A, A, B, A]`,那会出现两个 A 节(中间夹了一个 B)。所以如果你的数据需要全局按首字母分组,必须先排好序。
99+
section 是基于**连续相同值**来分组的,不是全局去重。如果你的模型数据是 `[A, A, B, A]`,那会出现两个 A 节(中间夹了一个 B)。所以如果你的数据需要全局按首字母分组,必须先排好序。
100100

101101
### 3.3 QSortFilterProxyModel 在 QML 中注册和使用
102102

tutorial/advanced/06-qml/07-qml-async-workerscript-advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Loader {
164164

165165
`asynchronous: true` 特别适合应用启动时按需加载的功能模块——比如设置面板、数据报表页面、复杂的对话框。这些页面不需要在启动时就存在,等到用户第一次点击对应的入口时再异步加载,既减少了启动时间,又避免了加载过程中的 UI 卡顿。
166166

167-
需要注意的是,异步 Loader 在加载完成之前 `item` 属性是 `null`。如果你在其他地方引用了 `heavyLoader.item.someProperty`,在加载完成之前会报 `Cannot read property of null` 错误。解决方案是所有对 `item` 的访问都加上 `if (item)` 守卫,或者通过 `onLoaded` 信号触发后续操作。
167+
异步 Loader 在加载完成之前 `item` 属性是 `null`。如果你在其他地方引用了 `heavyLoader.item.someProperty`,在加载完成之前会报 `Cannot read property of null` 错误。解决方案是所有对 `item` 的访问都加上 `if (item)` 守卫,或者通过 `onLoaded` 信号触发后续操作。
168168

169169
## 4. 踩坑预防
170170

tutorial/beginner/00-environment-setup/01-ide-setup-beginner.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ QLoggingCategory::setFilterRules("qt.core.qobject.connect=true");
206206
207207
[Qt Creator 手册](https://doc.qt.io/qtcreator/) · 官方 IDE 的完整文档
208208
[VS Code C++ 教程](https://code.visualstudio.com/docs/cpp/config-mingw) · 微软官方配置指南
209-
[CLion CMake 教程](https://www.jetbrains.com/help/clion/cmake-support.html) · JetBrains CMake 支持
209+
[CLion CMake 教程](https://www.jetbrains.com/help/clion/quick-cmake-tutorial.html) · JetBrains CMake 支持
210210
211211
*(链接已验证,2026-03-17 可访问)*
212212

0 commit comments

Comments
 (0)