- 桌面应用
- 跨平台
【免费下载链接】nodegui
A library for building cross-platform native desktop applications with Node.js and CSS 🚀. React NodeGui : https://react.nodegui.org and Vue NodeGui: https://vue.nodegui.org
本文围绕 NodeGui 生成的 API 参考页 QIconState 展开,系统讲解该枚举在图标体系中的定位、Off/On两个成员的语义、它在QIcon各方法中的参数默认值,以及从 TypeScript 层到 C++ N-API 绑定的完整透传链路。读完后,你将掌握如何基于QIconState为同一图标准备"选中/未选中"两套像素资源,并理解 state 参数在整个调用链上是如何被逐层解析的。
QIconState 的定义与成员
QIconState是 NodeGui 对 QtQIcon::State内嵌枚举的 JavaScript 镜像,定义在 QIcon.ts:
export enum QIconState { Off, On, }两个成员含义(对应 Qt 的QIcon::State):
| 成员 | 数值 | 语义 |
|---|---|---|
Off | 0 | 图标的"关"状态,即默认、未激活、未选中形态 |
On | 1 | 图标的"开"状态,即激活、选中、勾选形态 |
Off与On的设计目标是让一个QIcon能够同时携带多套像素:例如复选框/切换类控件的图标,未勾选时用Off版本,勾选后切换到On版本。该枚举通过 src/index.ts 从包入口统一导出,使用时可直接require('@nodegui/nodegui')后取用:
const { QIcon, QIconState } = require('@nodegui/nodegui');state 参数:QIcon 上所有接受它的 API
QIconState本身只是一个两值枚举,它的价值体现在QIcon类的多个方法签名中。对照 NodeGui 自动生成的类参考 QIcon 与源码 QIcon.ts,共有 6 个方法接收state参数,且默认值统一为QIconState.Off:
| 方法 | 签名(节选自源码) | state 默认值 |
|---|---|---|
actualSize | actualSize(size: QSize = null, mode = QIconMode.Normal, state = QIconState.Off): QSize | Off |
addFile | addFile(fileName: string, size: QSize = null, mode = QIconMode.Normal, state = QIconState.Off): void | Off |
addPixmap | addPixmap(pixmap: QPixmap, mode = QIconMode.Normal, state = QIconState.Off): void | Off |
availableSizes | availableSizes(mode = QIconMode.Normal, state = QIconState.Off): QSize[] | Off |
paint | paint(painter, x, y, w, h, alignment?, mode?, state?) | Off |
pixmap | pixmap(width, height, mode = QIconMode.Normal, state = QIconState.Off): QPixmap | Off |
值得注意的是pixmap的 JS 封装采用了"宽参"策略:它接收width、height两个数字而不是QSize对象,与 Qt 原生QPixmap pixmap(const QSize &size, ...)的签名略有差异。这一适配在 C++ 侧也有对应处理,见下文。
构造一个带 On/Off 双状态的图标
结合上面的 API,一个典型的"勾选状态图标"构建流程如下(基于源码中真实存在的方法组合,可复制运行):
const { QIcon, QIconState, QIconMode, QPixmap, QSize, QApplication } = require('@nodegui/nodegui'); const app = new QApplication([]); // 需要 QApplication 支撑位图资源 // 同一个 QIcon 上挂两套像素:未选中(Off) 与 选中(On) const icon = new QIcon(); icon.addPixmap(new QPixmap('unchecked.png'), QIconMode.Normal, QIconState.Off); icon.addPixmap(new QPixmap('checked.png'), QIconMode.Normal, QIconState.On); // 查询某个状态下有哪些可用尺寸 const offSizes = icon.availableSizes(QIconMode.Normal, QIconState.Off); const onSizes = icon.availableSizes(QIconMode.Normal, QIconState.On); offSizes.forEach((s: QSize) => console.log('Off size:', s.width, s.height)); // 按状态取位图:不传 state 时默认取 Off 状态 const offPixmap = icon.pixmap(64, 64, QIconMode.Normal, QIconState.Off); const onPixmap = icon.pixmap(64, 64, QIconMode.Normal, QIconState.On); // 查询在给定目标尺寸下图标实际会被缩放到多大 const fitted = icon.actualSize(new QSize(64, 64), QIconMode.Normal, QIconState.On); console.log('fitted size:', fitted.width, fitted.height);addFile与addPixmap是等价的资源注入方式,前者直接从文件路径加载(内部在 C++ 侧用QString::fromUtf8转码后调用QIcon::addFile),后者接收已构造的QPixmap对象。若图标被设置为 mask 图标(setIsMask(true)),state 的选取会进一步参与 Qt 对蒙版图标的渲染路径,这一点可从 qicon_wrap.cpp 中setIsMask的绑定得到印证。
C++ 绑定层:state 的透传与默认值处理
NodeGui 的架构是"JS 包装类 + N-API 绑定 + 原生 Qt 对象"三层结构。QIconState的数值在 qicon_wrap.cpp 中被static_cast<QIcon::State>还原为 Qt 枚举,例如actualSize的绑定(L67-L80):
QIcon::State state = static_cast<QIcon::State>(info[2].As<Napi::Number>().Int32Value()); QSize result = this->instance->actualSize(*size, mode, state);addFile(L82-L95)、addPixmap(L97-L108)、availableSizes(L110-L123)、paint(L163-L180)均遵循同样的模式:把 JS 数字参数按位宽转为Int32,再强转为QIcon::State传给原生QIcon实例。
有一个实现细节值得注意:pixmap的 C++ 绑定对 mode/state 做了"缺省即默认"的兜底(L132-L142):
QIcon::State state = QIcon::Off; if (info.Length() > 3) { int stateInt = info[3].As<Napi::Number>().Int32Value(); state = static_cast<QIcon::State>(stateInt); }也就是说,即使绕过 JS 层默认参数直接调用底层方法,state 缺失时也会落回QIcon::Off,与文档声明的默认值QIconState.Off保持一致。这解释了为什么在 QIcon 的每个方法参数表中,state一列的 Default 都是QIconState.Off。
与 QIconMode 的协作关系
state永远与mode成对出现。QIconMode定义于 QIcon.ts,取值为Normal、Disabled、Active、Selected,对应 Qt 的QIcon::Mode;其参考页见 QIconMode。两者的正交组合意味着:一个图标最多可以携带 4 种模式 × 2 种状态共 8 套像素。在 NodeGui 中,图标通常经由控件 API 消费,例如 QAbstractButton.setIcon 和 QAction.setIcon 只负责传入QIcon对象,随后由 Qt 根据控件自身的选中/悬停等状态自动挑选合适的 mode/state 版本来绘制——这正是把On/Off两套资源注册进同一个QIcon的实际意义所在。
测试用例中的验证
仓库现有的 Jest 测试 QIcon.test.ts 覆盖了QIcon的构造与cacheKey行为:
it('initialize with string', () => { const icon = new QIcon(testImagePath); expect(icon).toBeTruthy(); }); it('returns the cache Key', () => { const icon = new QIcon(testImagePath); const cacheKey = icon.cacheKey(); expect(Number.isInteger(cacheKey)).toBe(true); });当前测试未直接对QIconState.On的像素选取做断言,这属于该测试集的覆盖边界;若需要自证 state 生效,可参照上文"构造一个带 On/Off 双状态的图标"一节,比较两种状态下pixmap()返回结果或actualSize()的结果差异。
小结与参考路径
QIconState虽然只有Off、On两个成员,但它是 NodeGui 图标 API 中"双状态图标"能力的开关位:所有QIcon方法中 state 参数默认Off,与QIconMode正交组合,并在 C++ 绑定层被逐位还原为 Qt 的QIcon::State。核心参考路径汇总:
- 枚举定义:src/lib/QtGui/QIcon.ts
- 方法签名与默认值:src/lib/QtGui/QIcon.ts
- C++ 绑定实现:src/cpp/lib/QtGui/QIcon/qicon_wrap.cpp
- 绑定声明:src/cpp/include/nodegui/QtGui/QIcon/qicon_wrap.h
- 类级 API 参考:website/docs/api/generated/classes/qicon.md
- 测试用例:src/lib/QtGui/tests/QIcon.test.ts
- 桌面应用
- 跨平台
【免费下载链接】nodegui
A library for building cross-platform native desktop applications with Node.js and CSS 🚀. React NodeGui : https://react.nodegui.org and Vue NodeGui: https://vue.nodegui.org
相关推荐
Oralyzer与其他安全工具对比:为什么它是Open Redirection检测的首选?
Oralyzer与其他安全工具对比:为什么它是Open Redirection检测的首选? Open Redirection(开放重定向)漏洞是Web应用中常见
NodeGui 中的 MovieState 枚举:理解 QMovie 动图播放状态的完整指南
NodeGui 中的 MovieState 枚举:理解 QMovie 动图播放状态的完整指南 导读 MovieState 是 NodeGui 中用于描述 QMo
桌面应用跨平台NodeGui 中 QAbstractItemViewSelectionBehavior 枚举详解:控制 Item 视图的行、列与项选择行为
NodeGui 中 QAbstractItemViewSelectionBehavior 枚举详解:控制 Item 视图的行、列与项选择行为 本文围绕 Node
桌面应用跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考