桌面应用跨平台【免费下载链接】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点击查看免费下载QDoubleSpinBox是 NodeGui 对 QtQDoubleSpinBox原生控件的 TypeScript 封装用于在桌面应用中创建支持小数输入与步进调节的双精度数值输入框。本文以 qdoublespinbox.md 的 API 参考为主线结合 QDoubleSpinBox.ts、QAbstractSpinBox.ts 与 C 包装层 qdoublespinbox_wrap.cpp 的源码实现系统讲解其构造方式、数值控制 API、信号事件与底层原理读完即可在 NodeGui 应用中熟练使用该控件。控件概览与适用场景根据官方 API 文档的描述QDoubleSpinBoxprovides ability to add and manipulate native double spin box widgets即创建并操控原生双精度微调框double spin box控件。它适合需要让用户通过上下按钮或直接输入来调节小数数值的场景例如设置音量百分比、缩放比例、温度、尺寸或价格等参数。在 NodeGui 的项目结构中该类的 TypeScript 实现位于 src/lib/QtWidgets/QDoubleSpinBox.tsC 原生绑定层位于 src/cpp/lib/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.cppAPI 参考文档生成于 website/docs/api/generated/classes/qdoublespinbox.md。最小示例文档开头给出的最简用法如下const { QDoubleSpinBox } require(nodegui/nodegui); const doublespinBox new QDoubleSpinBox();当不传入任何参数时会创建一个没有父级的独立微调框实例。在真实应用中通常还会将其加入某个布局或设置父窗口并配置取值范围、小数位、前缀后缀等属性。类层次与继承关系文档中明确给出了完整的类层次↳ QAbstractSpinBoxQDoubleSpinBoxSignals ↳ QDoubleSpinBoxQDoubleSpinBox直接继承自 QAbstractSpinBox一个带泛型信号参数的抽象基类并进一步向上继承QWidget、YogaWidget、EventWidget、Component、QObject等 NodeGui 基础类。这一点在源码中可以直接验证export class QDoubleSpinBox extends QAbstractSpinBoxQDoubleSpinBoxSignals { // ... } export interface QDoubleSpinBoxSignals extends QAbstractSpinBoxSignals { valueChanged: (value: number) void; }信号接口 QDoubleSpinBoxSignals 在QAbstractSpinBoxSignals提供editingFinished的基础上增加了valueChanged用于在数值变化时通知 JS 侧。说明在生成的 API 文档中大量通用方法被标注为 Inherited from QMenu。从 QWidget.ts 的源码结构看这些其实是QWidget提供的通用窗口控件能力文档生成器在展示继承链时将其归属到了QMenu名下阅读 API 文档时不必因此产生困惑。构造函数三种创建路径文档定义的构造签名如下new QDoubleSpinBox(arg?: QWidgetQWidgetSignals | NativeElement): QDoubleSpinBox参数arg可选既可以是 QWidget作为父控件也可以是 NativeElement已有原生实例用于包装复用。TS 层的构造逻辑QDoubleSpinBox.tsconstructor(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.QDoubleSpinBox(parent.native); } else { native new addon.QDoubleSpinBox(); } super(native); }三种分支对应调用方式行为new QDoubleSpinBox()创建无父级的新实例new QDoubleSpinBox(parentWidget)以已有QWidget为父控件创建实例new QDoubleSpinBox(nativeElement)包装一个已存在的原生QDoubleSpinBox实例底层的 C 构造逻辑与此一一对应qdoublespinbox_wrap.cpp无参数时执行new NDoubleSpinBox()参数为External时直接包装传入的QDoubleSpinBox*参数为对象时通过NodeWidgetWrap解包父控件并执行new NDoubleSpinBox(parent)。NDoubleSpinBox是仓库自定义的QDoubleSpinBox子类这也是所有 NodeGui 控件统一采用的以子类挂钩 Qt 事件系统的实现模式。核心数值控制 API 详解以下是QDoubleSpinBox自身定义的方法均在 QDoubleSpinBox.ts 中实现是使用该控件最关键的接口。当前值value / setValuesetValue(val: number): void { this.setProperty(value, val); } value(): number { return this.property(value).toDouble(); }setValue(val)设置当前数值value()读取当前数值double类型。与QAbstractSpinBox的步进器属性一样这里的读写都通过 Qt 动态属性系统完成——TS 层调用setProperty(value, val)后由原生层把 JS 数字写入 Qt 控件的value属性读取时用property(value).toDouble()转回 JS number。取值范围setMinimum / setMaximum / setRangesetMaximum(max: number): void { this.setProperty(maximum, max); } maximum(): number { return this.property(maximum).toDouble(); } setMinimum(min: number): void { this.setProperty(minimum, min); } minimum(): number { return this.property(minimum).toDouble(); } setRange(minimum: number, maximum: number): void { this.native.setRange(minimum, maximum); }setRange(minimum, maximum)是唯一一个不走属性系统、而是直接调用原生方法的接口它委托给 C 层的QDoubleSpinBoxWrap::setRangeqdoublespinbox_wrap.cpp后者把两个 JS number 转成double后调用instance-setRange(minimum, maximum)。而setMinimum/setMaximum则分别通过属性系统修改单侧边界。三者配合可精确约束用户可输入的数值范围越界输入会被 Qt 自动纠正。小数精度setDecimals / decimalssetDecimals(prec: number): void { this.setProperty(decimals, prec); } decimals(): number { return this.property(decimals).toInt(); }setDecimals(prec)设置显示的小数位数decimals()以整数返回当前精度。例如设置为 2 时控件将始终以两位小数格式显示与解析数值。步进setSingleStep / singleStep 与 setStepType / stepTypesetSingleStep(val: number): void { this.setProperty(singleStep, val); } singleStep(): number { return this.property(singleStep).toDouble(); } setStepType(stepType: StepType): void { this.setProperty(stepType, stepType); } stepType(): StepType { return this.property(stepType).toInt(); }setSingleStep(val)决定点击上下按钮或按方向键时数值的单次增减量setStepType可切换步进模式。StepType枚举定义在 QAbstractSpinBox.tsexport enum StepType { DefaultStepType, // 固定使用 singleStep 步进 AdaptiveDecimalStepType, // 根据小数位自适应步进 }默认模式DefaultStepType使用固定的singleStepAdaptiveDecimalStepType会根据当前小数点位置自动调整步长适合大范围数值的精细调节场景。显示格式setPrefix / prefix 与 setSuffix / suffixsetPrefix(prefix: string): void { this.setProperty(prefix, prefix); } prefix(): string { return this.property(prefix).toString(); } setSuffix(suffix: string): void { this.setProperty(suffix, suffix); } suffix(): string { return this.property(suffix).toString(); }setPrefix/setSuffix分别设置显示文本的固定前缀与后缀例如前缀$、后缀 kg。注意前缀后缀只影响显示value()仍返回纯数值而cleanText()返回的是去除前后缀后的文本。文本转换cleanText / textFromValue / valueFromTextcleanText(): string { return this.property(cleanText).toString(); } textFromValue(value: number): string { return this.native.textFromValue(value); } valueFromText(text: string): number { return this.native.valueFromText(text); }cleanText()返回去掉前缀、后缀与空格后的纯文本内容适合表单校验时读取textFromValue(value)按当前格式小数位、前缀后缀把数值渲染成文本委托给原生QDoubleSpinBoxWrap::textFromValueqdoublespinbox_wrap.cppvalueFromText(text)反向解析文本为数值用于自定义文本校验或程序化输入同样委托原生实现qdoublespinbox_wrap.cpp。继承自 QAbstractSpinBox 的通用能力QAbstractSpinBox是QSpinBox、QDateTimeEdit等步进控件的抽象基类QAbstractSpinBox.ts 中实现的这些方法同样适用于QDoubleSpinBox方法说明setWrapping(w)/wrapping()开启循环取值超过最大值后回绕到最小值setReadOnly(r)/isReadOnly()只读模式禁止编辑仍可选择与复制文本setSpecialValueText(txt)/specialValueText()当值等于最小值时显示的特殊文本如 AutosetGroupSeparatorShown(shown)/isGroupSeparatorShown()是否显示千分位分隔符属性名为showGroupSeparatorsetButtonSymbols(bs)/buttonSymbols()步进按钮的符号样式setCorrectionMode(cm)/correctionMode()输入无效时的纠正策略setAlignment(alignment)/alignment()文本对齐方式取值见 AlignmentFlagsetKeyboardTracking(kt)/keyboardTracking()键盘输入时是否实时发射valueChangedsetAccelerated(on)/isAccelerated()长按按钮是否加速步进setFrame(enable)/hasFrame()是否绘制边框hasAcceptableInput()当前文本是否满足输入要求selectAll()/stepUp()/stepDown()全选文本 / 向上步进 / 向下步进其中三个关键枚举同样定义在 QAbstractSpinBox.tsexport enum ButtonSymbols { UpDownArrows, // 上下箭头 PlusMinus, // 加减号 NoButtons, // 不显示按钮 } export enum CorrectionMode { CorrectToPreviousValue, // 无效输入恢复为上一个合法值 CorrectToNearestValue, // 无效输入纠正到最近的合法值 }这些方法大多通过setProperty走 Qt 属性系统属性名与 Qt 原生属性一致如wrapping、readOnly、showGroupSeparator、frame、accelerated可放心与 Qt 文档对照使用。信号与事件处理QDoubleSpinBox通过addEventListener监听信号接口定义如下文档 QDoubleSpinBox.ts信号回调签名触发时机valueChanged(value: number) void数值发生变化时含程序化修改editingFinished() void用户完成编辑回车或失焦时用法示例沿袭文档中QPushButton的监听模式const { QDoubleSpinBox } require(nodegui/nodegui); const spin new QDoubleSpinBox(); spin.addEventListener(valueChanged, (value) { console.log(当前数值, value); }); spin.addEventListener(editingFinished, () { console.log(编辑完成); });addEventListener由 EventWidget 提供支持两种重载一种是基于信号名的类型安全监听如上例另一种是基于WidgetEventTypes的低层原生事件监听例如文档中展示的button.addEventListener(WidgetEventTypes.HoverEnter, () console.log(hovered));此外setEventProcessed(isProcessed)可在事件回调中将当前事件标记为已处理使 NodeGui 的QObject::event()直接返回true并跳过父类处理用于拦截默认行为eventProcessed()用于读取该标记状态。QWidget 通用能力速览除数值与步进相关方法外QDoubleSpinBox还完整继承了 QWidget 与 QObject 的能力API 文档中按类别可归纳为窗口管理show()、hide()、close()、showFullScreen()、showMaximized()、showMinimized()、activateWindow()、setWindowTitle()、setWindowOpacity()等几何尺寸resize()、move()、geometry()、setFixedSize()、setMinimumSize()、setMaximumSize()、sizeHint()、minimumSizeHint()等外观样式setStyleSheet()、setInlineStyle()、setFont()、setCursor()、setGraphicsEffect()等焦点与交互setFocus()、setFocusPolicy()、clearFocus()、setMouseTracking()、grabMouse()等布局setLayout()、layout()、setSizePolicy()、setSizeIncrement()等拖放与辅助功能setAcceptDrops()、setAccessibleName()、setToolTip()、setStatusTip()、setWhatsThis()等对象生命周期delete()、deleteLater()、children()、setParent()、property()、setProperty()、startTimer()、killTimer()、_id()返回标识底层 C 对象的哈希 ID可用于配合setLogCreateQObject()/setLogDestroyQObject()排查内存问题等。从 Component 继承的属性native原生实例引用与type控件类型字符串以及从 YogaWidget 继承的getFlexNode()、setFlexNodeSizeControlled()则使QDoubleSpinBox可以像 NodeGui 其他控件一样参与 Flex 布局相关机制见 FlexLayout.ts 与 YogaWidget.ts。底层实现原理从 C 包装层可以清晰地看到 NodeGui 的桥接模式。QDoubleSpinBoxWrap::initqdoublespinbox_wrap.cpp完成了三件事以QDoubleSpinBox为名注册 N-API 类只显式绑定三个实例方法setRange、textFromValue、valueFromText其余方法通过宏QABSTRACTSPINBOX_WRAPPED_METHODS_EXPORT_DEFINE批量导出这也是为什么 TS 层大部分属性方法走setProperty而非逐个绑定——Qt 属性系统本身就是通用的读写通道通过QOBJECT_REGISTER_WRAPPER把该类注册进 NodeGui 的包装器缓存。TS 层与之对应在 QDoubleSpinBox.ts 末尾执行wrapperCache.registerWrapper(QDoubleSpinBoxWrap, QDoubleSpinBox);这套TS 封装 N-API 原生类 WrapperCache 注册的架构与仓库文档 wrapper_caching.md 中描述的一致当 C 事件系统把原生对象交还给 JS 侧时WrapperCache 能复现出对应的 TS 包装实例保证同一控件的native与信号回调指向同一个对象。综合实战示例将上述能力组合可得到一个带样式、范围约束、前后缀与信号反馈的完整示例const { QMainWindow, QDoubleSpinBox, QWidget, QBoxLayout, Direction, ButtonSymbols, } require(nodegui/nodegui); const win new QMainWindow(); win.setWindowTitle(QDoubleSpinBox 示例); win.resize(320, 120); const central new QWidget(); win.setCentralWidget(central); const layout new QBoxLayout(Direction.LeftToRight); central.setLayout(layout); const spin new QDoubleSpinBox(); spin.setRange(0, 100); // 取值范围 0 ~ 100 spin.setDecimals(2); // 两位小数 spin.setSingleStep(0.5); // 每步 0.5 spin.setPrefix($ ); // 前缀 $ spin.setSuffix( 元); // 后缀 元 spin.setValue(12.5); spin.setButtonSymbols(ButtonSymbols.UpDownArrows); spin.setGroupSeparatorShown(true); spin.setStyleSheet(padding: 4px; border: 1px solid #ccc;); spin.addEventListener(valueChanged, (value) { console.log(已选金额${value}); }); layout.addWidget(spin); win.show();运行后即可得到一个原生渲染的双精度数值输入框点击上下按钮按0.5步进直接输入文本会被自动解析并按两位小数与取值范围纠正数值变化时触发valueChanged回调。该控件与QSpinBox整数的区别在于全程以double精度处理数值适用于小数参数调节类表单。如需进一步查阅完整方法列表与信号签名可继续阅读 qdoublespinbox.md、qabstractspinbox.md 以及信号接口 qdoublespinboxsignals.md源码实现位于 src/lib/QtWidgets/QDoubleSpinBox.ts 与 src/cpp/lib/QtWidgets/QDoubleSpinBox/qdoublespinbox_wrap.cpp。赞分享桌面应用跨平台【免费下载链接】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点击查看免费下载相关推荐使用NodeGui构建高性能原生跨平台桌面应用使用NodeGui构建高性能原生跨平台桌面应用 在寻找一个既能提供高性能、又具备强大灵活性的解决方案来构建桌面应用程序吗NodeGui或许正是你需要的答案。这桌面应用跨平台OpenCore Legacy Patcher终极指南让老Mac焕发新生的简单方法OpenCore Legacy Patcher终极指南让老Mac焕发新生的简单方法 想象一下你的老MacBook Pro还能运行最新的macOS系统吗这听操作系统固件驱动开发Vitest pool 配置详解threads、forks、vmThreads 与 vmForks 的选型与源码实现Vitest pool 配置详解threads、forks、vmThreads 与 vmForks 的选型与源码实现 本文以 Vitest 官方配置文档 do桌面应用跨平台上一篇BeetleX高性能.NET Core网络通信组件下一篇Flutter 百分比指示器flutter_percent_indicator安装与使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考