ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

NodeGui 中的 QSpinBox 整数微调框:从属性配置到信号处理的完整实战指南

NodeGui 中的 QSpinBox 整数微调框:从属性配置到信号处理的完整实战指南 桌面应用跨平台【免费下载链接】nodeguiA 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项目地址https://gitcode.com/gh_mirrors/no/nodegui点击查看免费下载QSpinBox是 NodeGui 中对 QtQSpinBox原生组件的 JavaScript/TypeScript 封装用于在跨平台桌面应用中创建、控制整数微调框spin box。本文以 QSpinBox API 文档 为主体结合仓库中的 TypeScript 包装层与 C 原生实现系统讲解其构造方式、数值范围配置、前后缀与进制显示、继承自QAbstractSpinBox的全部能力、valueChanged信号处理以及内存生命周期管理读完即可在 NodeGui 应用中熟练落地带上下调节按钮的整数输入控件。类概览与继承层级QSpinBox用于提供一个整数输入框 上下调节按钮的原生控件用户既可以直接在文本框中键入整数也可以通过按钮步进增减。它默认支持int类型int32 位的取值范围适合数量、序号、比例等整数场景。从 API 文档的 Hierarchy 一节可以看到其继承链↳ QAbstractSpinBox‹QSpinBoxSignals› ↳ QSpinBox即QSpinBox继承自抽象基类QAbstractSpinBox再往上依次是QWidget、NodeWidget、EventWidget、Component、QObject。由于QAbstractSpinBox是抽象类实际可实例化的是QSpinBox同族还有QDateTimeEdit因此在 NodeGui 中所有微调框相关的通用行为都被收拢在抽象层而QSpinBox提供整数特化的能力。创建控件的最小示例出自 API 文档与 QSpinBox.ts 源码注释const { QSpinBox } require(nodegui/nodegui); const spinBox new QSpinBox();从 TypeScript 源码 可以看到构造函数的重载逻辑constructor(arg?: QWidgetQWidgetSignals | NativeElement) { let native: NativeElement; if (checkIfNativeElement(arg)) { native arg as NativeElement; } else if (arg ! null) { const parent arg as QWidget; native new addon.QSpinBox(parent.native); } else { native new addon.QSpinBox(); } super(native); }无参构造new QSpinBox()创建一个独立的原生微调框传入父控件new QSpinBox(parentWidget)将控件挂到指定父QWidget下由父控件负责布局与生命周期传入 NativeElement用于包装已存在的原生实例多用于跨层传递。对应的 C 构造逻辑在 qspinbox_wrap.cpp无参时new NSpinBox()带参且参数为外部对象时包装既有实例否则从NodeWidgetWrap解包父控件后new NSpinBox(parentWidget-getInternalInstance())最后通过configureQWidget完成原生控件与 Flex 布局节点的对接。核心数值属性value、minimum、maximum 与 setRangeQSpinBox最核心的数据模型是整数 取值范围 步进。API 文档与本类直接定义的属性方法包括setValue/value、setMinimum/minimum、setMaximum/maximum、setRange、setSingleStep/singleStep、setStepType/stepType以及显示相关的setPrefix/prefix、setSuffix/suffix、setDisplayIntegerBase/displayIntegerBase、cleanText。当前值setValue / valuespinBox.setValue(42); const current spinBox.value(); // 42源码实现 中setValue/value都通过 Qt 属性系统读写setValue(val: number): void { this.setProperty(value, val); } value(): number { return this.property(value).toInt(); }注意setValue传入的值会自动被钳制clamp到[minimum, maximum]区间内因此传入超出范围的值不会抛出异常而是收敛到边界值。取值范围setMinimum / setMaximum / setRangespinBox.setMinimum(0); spinBox.setMaximum(100); // 等价于一次性设置 spinBox.setRange(0, 100);setRange(minimum, maximum)是唯一一个在 C 侧原生实现的调用而非通过属性系统qspinbox_wrap.cpp 中将其映射到QSpinBox::setRangeNapi::Value QSpinBoxWrap::setRange(const Napi::CallbackInfo info) { Napi::Number minimum info[0].AsNapi::Number(); Napi::Number maximum info[1].AsNapi::Number(); this-instance-setRange(minimum.Int32Value(), maximum.Int32Value()); return env.Null(); }从 C 头文件声明 可见setRange是本类自定义暴露给 JS 的唯一方法其余方法全部复用QABSTRACTSPINBOX_WRAPPED_METHODS_DECLARATION宏生成的通用接口。Qt 语义上setRange会保证minimum maximum若传入的最小值大于最大值会先交换两者再调整当前值。步进setSingleStep / setStepTypespinBox.setSingleStep(5); // 点击一次按钮增减 5 const step spinBox.singleStep(); // 5singleStep默认值为 1决定每次点击上下按钮或按上下方向键时数值的增减幅度。stepType控制步进行为模式取值来自QAbstractSpinBox.ts中定义的枚举见 src/lib/QtWidgets/QAbstractSpinBox.ts枚举值含义StepType.DefaultStepType默认模式每次固定步进singleStep的数值StepType.AdaptiveDecimalStepType自适应十进制步进根据当前数值大小动态调整步进幅度数值越大单次步进越大spinBox.setStepType(StepType.AdaptiveDecimalStepType);显示格式prefix、suffix、displayIntegerBase 与 cleanTextQSpinBox允许在不影响内部数值的前提下定制显示文本spinBox.setPrefix($ ); // 数值前显示货币符号 spinBox.setSuffix( px); // 数值后显示单位 spinBox.setDisplayIntegerBase(16); // 以十六进制显示setPrefix/prefix在数值前拼接前缀文本例如$ 、#setSuffix/suffix在数值后拼接后缀文本例如px、%setDisplayIntegerBase/displayIntegerBase设置整数显示的进制基数默认为 10十进制。设为 16 时数值以十六进制显示设为 2 即以二进制显示适合做进制转换类工具。注意显示进制不影响value()返回的十进制数值也不影响步进计算。这三个方法在 QSpinBox.ts 中同样走 Qt 属性系统displayIntegerBase读取时toInt()转换。spinBox.setPrefix(#); spinBox.setDisplayIntegerBase(16); spinBox.setValue(255); spinBox.text(); // #ff spinBox.cleanText(); // ff —— 不含前缀、后缀及空格text()继承自QAbstractSpinBox返回带前缀/后缀的完整显示文本cleanText()QSpinBox自有方法返回去除前缀、后缀和空格后的纯数值文本适合在提交时做字符串解析。源码实现cleanText(): string { return this.property(cleanText).toString(); }继承自 QAbstractSpinBox 的通用配置QSpinBox从抽象基类继承了整套通用能力对应 API 文档中标有Inherited from QAbstractSpinBox的方法。它们定义在 QAbstractSpinBox.ts全部通过 Qt 属性系统读写外观与对齐spinBox.setAlignment(AlignmentFlag.AlignCenter); // 文本对齐方式 spinBox.setButtonSymbols(ButtonSymbols.UpDownArrows); // 按钮符号样式 spinBox.setFrame(true); // 是否绘制边框 spinBox.setGroupSeparatorShown(true); // 千位分隔符1,000ButtonSymbols枚举src/lib/QtWidgets/QAbstractSpinBox.ts#L92-L96提供三种按钮形态枚举值按钮样式ButtonSymbols.UpDownArrows默认的上下箭头ButtonSymbols.PlusMinus加减号按钮ButtonSymbols.NoButtons不显示按钮纯输入框输入与校验spinBox.setReadOnly(true); // 只读禁止编辑 spinBox.setKeyboardTracking(false); // 关闭按键跟踪 spinBox.setAccelerated(true); // 按住按钮持续加速步进 spinBox.setCorrectionMode(CorrectionMode.CorrectToNearestValue); const ok spinBox.hasAcceptableInput(); // 当前文本是否合法可接受setKeyboardTracking(false)默认情况下用户每敲一个字符valueChanged都会触发关闭后仅在回车或失焦editingFinished时才提交适合大数据量重绘场景CorrectionMode枚举src/lib/QtWidgets/QAbstractSpinBox.ts#L98-L101CorrectToPreviousValue输入非法时回退到上一个合法值与CorrectToNearestValue钳制到最接近的合法值。边界行为与快捷操作spinBox.setWrapping(true); // 超过最大值后循环回最小值 spinBox.setSpecialValueText(Empty); // 数值为最小值时显示替代文本 spinBox.selectAll(); // 选中全部文本 spinBox.stepUp(); // 程序化步进 1 spinBox.stepDown(); // 程序化步进 -1 const t spinBox.text(); // 当前显示文本setSpecialValueText常用于最小值即特殊状态的场景例如最小值 0 且文案为 0 时可显示成 Free 或 Off此时value()返回的仍是数值 0text()返回特殊文本。信号处理valueChanged 与 editingFinishedQSpinBox支持两类事件监听对应 API 文档 addEventListener 小节 的两种签名1. 信号监听SignalQSpinBoxSignals接口定义了本类自有信号QSpinBox.tsexport interface QSpinBoxSignals extends QAbstractSpinBoxSignals { valueChanged: (value: number) void; }继承的QAbstractSpinBoxSignals还包含editingFinished: () void。spinBox.addEventListener(valueChanged, (value) { console.log(当前值, value); }); spinBox.addEventListener(editingFinished, () { console.log(编辑结束提交值, spinBox.value()); });信号在 C 原生侧通过事件发射器桥接到 Node.js。在 nspinbox.hpp 中可以看到valueChanged的底层连接逻辑——使用QOverloadint明确匹配QSpinBox::valueChanged(int)重载因为 Qt 中还存在valueChanged(const QString)重载将数值作为参数回传给 JS 回调QObject::connect( this, QOverloadint::of(QSpinBox::valueChanged), { Napi::Env env this-emitOnNode.Env(); Napi::HandleScope scope(env); this-emitOnNode.Call({Napi::String::New(env, valueChanged), Napi::Value::From(env, val)}); });2. 事件监听WidgetEventTypesconst { WidgetEventTypes } require(nodegui/nodegui); spinBox.addEventListener(WidgetEventTypes.KeyPress, (event) { console.log(spinBox 内按键事件); });removeEventListener(signalType, callback)与addEventListener对称用于移除已注册的回调。若在事件回调中需要阻止事件继续传播可调用setEventProcessed(true)配合eventProcessed()查询状态——当置位后 NodeGui 的QObject::event()会直接返回 true 而不再调用父类event()。样式、Flex 布局与组合示例QSpinBox属于QWidget体系天然支持 NodeGui 的 Flexbox 布局与样式系统const { QSpinBox, QWidget, FlexLayout } require(nodegui/nodegui); const container new QWidget(); container.setObjectName(root); container.setLayout(new FlexLayout()); const spinBox new QSpinBox(); spinBox.setRange(0, 100); spinBox.setValue(50); spinBox.setSingleStep(5); spinBox.setPrefix($ ); spinBox.setSuffix( 元); spinBox.setStyleSheet(background-color: #f0f0f0; color: #333;); container.layout.addWidget(spinBox);setStyleSheet(styleSheet, postprocesstrue)应用 QSS 样式与setInlineStyle类似第二个参数控制是否后处理可从 QWidget.ts 的对应实现继承而来setFixedWidth(w)/setFixedHeight(h)/setMinimumSize(w,h)/setMaximumSize(w,h)等尺寸约束方法与所有QWidget一致若希望尺寸由 Flex 布局完全接管可用setFlexNodeSizeControlled(true)API 文档说明将控件尺寸控制权交给外部例如窗口被拖拽时由窗口框架控制其大小。生命周期与内存管理QSpinBox的实例管理继承自QObject/Component体系native属性继承自Component持有底层原生句柄NativeElement | null_id()返回标识底层 C 对象的哈希数字配合setLogCreateQObject()/setLogDestroyQObject()可排查 C 对象泄漏delete()/deleteLater()销毁底层对象。C 侧 qspinbox_wrap.cpp 的析构函数调用extrautils::safeDelete(this-instance)保证 JS 侧释放时原生QSpinBox同步回收。NodeGui 通过wrapperCache.registerWrapper(QSpinBoxWrap, QSpinBox)见 QSpinBox.ts注册包装类使同一原生对象多次回传 JS 时复用同一包装实例避免重复包装。setLogCreateQObject()与setLogDestroyQObject()是QObject提供的日志开关可观察包装对象的创建/销毁时序。一个包含信号监听的完整可运行示例const { QSpinBox, QMainWindow, QLabel, FlexLayout } require(nodegui/nodegui); const win new QMainWindow(); const root new QWidget(); root.setLayout(new FlexLayout()); win.setCentralWidget(root); const label new QLabel(); const spinBox new QSpinBox(); spinBox.setRange(0, 255); spinBox.setSingleStep(10); spinBox.setPrefix(亮度: ); spinBox.setValue(128); label.setText(当前亮度: ${spinBox.value()}); spinBox.addEventListener(valueChanged, (value) { label.setText(当前亮度: ${value}); }); root.layout.addWidget(spinBox); root.layout.addWidget(label); win.show();小结QSpinBox 使用速查构造new QSpinBox()或new QSpinBox(parent)数值域setRange(min, max)、setMinimum、setMaximum、setValue、value步进setSingleStep、setStepType(AdaptiveDecimalStepType)显示setPrefix、setSuffix、setDisplayIntegerBase、cleanText、setSpecialValueText通用配置setButtonSymbols、setWrapping、setReadOnly、setKeyboardTracking、setCorrectionMode、setGroupSeparatorShown信号valueChanged、editingFinished、WidgetEventTypes.*样式与布局setStyleSheet/setInlineStyle、FlexLayout、尺寸约束方法内存delete()/deleteLater()必要时用_id()结合创建/销毁日志排查泄漏。如需进一步查阅完整方法签名包括全部继承自QWidget/QMenu的窗口与几何方法可继续阅读 QSpinBox API 文档、抽象基类 QAbstractSpinBox 文档以及相关源码 src/lib/QtWidgets/QSpinBox.ts、src/lib/QtWidgets/QAbstractSpinBox.ts 与原生层 qspinbox_wrap.cpp、nspinbox.hpp。赞分享桌面应用跨平台【免费下载链接】nodeguiA 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项目地址https://gitcode.com/gh_mirrors/no/nodegui点击查看免费下载相关推荐终极ArduinoFFT信号处理实战从入门到精通的完整指南终极ArduinoFFT信号处理实战从入门到精通的完整指南 ArduinoFFT是一款专为Arduino平台设计的快速傅里叶变换FFT库能够帮助开发者轻音频处理嵌入式HackRF信号解调实战从IQ数据到音频信号的完整流程指南HackRF信号解调实战从IQ数据到音频信号的完整流程指南 想要掌握软件定义无线电的核心技能吗HackRF One作为低成本软件无线电平台的代表能够让你从嵌入式硬件开发固件通信SerenityOS posix_spawnattr 完整指南配置子进程属性与信号默认处理SerenityOS posix_spawnattr 完整指南配置子进程属性与信号默认处理 导读 posix_spawnattr_t 是 POSIX posi操作系统内核驱动上一篇FakeLocation终极指南三步实现应用级位置模拟完美保护隐私与突破地理限制下一篇3种创新用法重新定义你的数字足迹管理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表