桌面应用跨平台【免费下载链接】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),仅供参考
企业数字化 ERP 产品动态
相关推荐
昇腾Atlas 300V 24G部署YOLO全攻略:从模型转换到性能调优 干过Atlas系列卡(300V、310P、500系列)的都知道,这卡最容易让人懵的地方在于:它长得像GPU、名字带算力、但驱动和工具链完全是另一套玩法。尤其是最近不少朋友问“atlas 300v 24g 是运算加速卡吗”“atlas部署yolo能不能搞”&… · 2026/9/25 13:08:49
LeanCTX Context Time Machine:如何用git锚定签名快照回放、恢复与共享上下文 LeanCTX Context Time Machine:如何用git锚定签名快照回放、恢复与共享上下文 【免费下载链接】lean-ctx LeanCTX — Context Intelligence for AI systems. 项目地址: https://gitcode.com/gh_mirrors/le/lean-ctx
你是否好奇过:你的 AI Agent 在… · 2026/9/25 13:08:37
微信小程序 WebSocket 智能机器人源码解析 简介:本资源是一套可直接运行的微信小程序智能机器人源码,面向前端初学者与小程序开发入门者,帮助快速理解对话类小程序的核心实现逻辑与基础交互设计。压缩包共19个文件,包含5个JS逻辑文件(处理用户输入、API调用与响… · 2026/9/25 13:38:22
BrowserSkill 隐私与权限架构全解:数据边界、12 项权限依据与源码级证据 BrowserSkill 隐私与权限架构全解:数据边界、12 项权限依据与源码级证据 【免费下载链接】BrowserSkill Let AI agents use your real, logged-in browser without interrupting your work. CLI extension for browser automation across any shell-capable AI age… · 2026/9/25 13:38:15
Python-面向对象编程 今日目标:理解 OOP 思想,掌握类与对象、封装、继承、多态,完成愤怒的小鸟案例设计一、面向过程 vs 面向对象面向过程面向对象(OOP)按步骤组织代码按对象组织代码函数是核心类是核心适合简单任务适合复杂系统面向对象三… · 2026/9/25 13:37:32
电子信息本科四年嵌入式/芯片方向学习规划:从STM32到Linux驱动 电子信息本科四年,听起来课表排得满满当当,但真正到了大三回头看,大家拉开差距的往往不是学校教了什么,而是自己在大一到大四的每个关键节点做了哪些"课外的正事"。嵌入式/芯片这条线尤其如此——它既不像纯软方向可以靠… · 2026/9/25 13:36:55
老旧PLC设备上云:Modbus转MQTT采集方案详解 老车间里那批装在配电柜深处的PLC和仪表,十有八九还靠RS485串口活着。设备是十几年前买的,程序是当年调试完就再没人碰过的,上位机软件跑在工控机上,数据出不了车间那堵墙。可现在上面要上物联网平台,要实时看产线能耗… · 2026/9/25 13:36:55
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37