桌面应用跨平台【免费下载链接】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点击查看免费下载导读QWheelEvent是 NodeGui基于 Qt 与 Node.js 构建跨平台原生桌面应用中负责滚轮鼠标滚轮 / 触控板手势事件的封装类。本文以 QWheelEvent 官方 API 文档 为核心骨架完整解析其全部构造器、属性与方法并结合仓库中的 TypeScript 封装层、C N-API 绑定与事件分发源码带你掌握如何在 NodeGui 应用中监听滚轮事件、读取角度增量与像素增量、判断滚动相位并正确处理事件传播最终写出手感接近原生的滚动交互。QWheelEvent 在 NodeGui 事件体系中的位置继承链与类型关系QWheelEvent不是独立存在的类型它在 NodeGui 中遵循 Qt 的继承结构直接继承 QSinglePointEvent进而继承 QInputEvent 与 QEvent因此它天然拥有事件对象的通用能力accept/ignore/isAccepted/setAccepted/spontaneous/type输入事件能力modifiers/timestamp以及单点事件能力buttons/position/globalPosition。对应地C 侧在 qwheelevent_wrap.h 中通过多个宏合并声明了四层方法COMPONENT_WRAPPED_METHODS_DECLARATION QEVENT_WRAPPED_METHODS_DECLARATION QINPUTEVENT_WRAPPED_METHODS_DECLARATION QSINGLEPOINTEVENT_WRAPPED_METHODS_DECLARATION并在 qwheelevent_wrap.cpp 中注册了事件专属方法angleDelta、inverted、phase、pixelDelta以及通过QEVENT_WRAPPED_METHODS_EXPORT_DEFINE等宏批量导出的继承方法。这些方法最终统一在 main.cpp 中通过QWheelEventWrap::init(env, exports)注册为原生 addon 的一部分并在 index.ts 中以export { QWheelEvent } from ./lib/QtGui/QEvent/QWheelEvent对外暴露。事件分发链路在 NodeGui 中滚轮事件并非凭空而来而是经由 EventWidget 这一事件中枢分发给 JavaScript原生侧 EventWidget::sendEventToNode 收到QEvent后通过EventsMap::eventTypes查出事件名字符串Wheel对应QEvent::Wheel见 eventsmap.cpp并把原生事件指针作为Napi::ExternalQEvent传给 JSJS 侧的回调通过wrapNative与registerNativeWrapFunction机制将原生对象包装成对应的 JS 类实例事件名以大写字母开头会被判定为 QEvent见 EventWidget.ts因此监听回调中拿到的第一个参数即原生事件需要手动用new QWheelEvent(nativeEvt)包装后使用。这意味着你在监听回调里拿到的原始对象并不是可直接调用 API 的QWheelEvent实例必须先经构造器包装这一点在实战代码中需要特别注意。构造器与属性constructor(event: NativeRawPointerQEvent)QWheelEvent的构造器接收一个原生事件指针返回一个新的QWheelEvent实例new QWheelEvent(event: NativeRawPointerQEvent): QWheelEventTypeScript 侧实现QWheelEvent.ts只是把原生对象传给addon.QWheelEventconstructor(event: NativeRawPointerQEvent) { super(new addon.QWheelEvent(event)); }C 侧构造器要求恰好 1 个参数Napi::ExternalQWheelEvent否则抛出 Wrong number of arguments 的TypeErrorqwheelevent_wrap.cpp。同时注意该包装类的析构函数刻意不销毁内部实例注释明确说明由 Qt 事件循环负责销毁因此你无需也不应手动管理滚轮事件对象的生命周期。native 属性native:NativeElement继承自 QEvent持有底层原生对象引用TypeScript 层所有方法最终都通过this.native.xxx()转发到底层 addon。方法逐一解析角度增量 angleDelta()angleDelta(): { x: number; y: number }返回滚轮旋转的相对角度单位为度的八分之一1/8 度正值表示滚轮向前远离用户滚动负值表示滚轮向后朝向用户滚动angleDelta().y提供普通垂直滚轮自上次事件以来的旋转角度angleDelta().x提供水平滚轮的角度若鼠标没有水平滚轮则保持为 0。支持滚轮左右倾斜、或触控板横向滚动手势的设备其值同样出现在x中。大多数鼠标以 15 度为一步滚动此时增量值为 120 的倍数120 单位 × 1/8 15 度。部分高分辨率滚轮会发送小于 120 的增量值小于 15 度。针对这类设备文档给出了两种处理策略将多次事件的 delta 值累积直到达到 120 再滚动一次控件每次滚轮事件都部分滚动控件。原文进一步建议在支持高分辨率像素增量的平台上优先使用pixelDelta()以获得更原生的手感。C 实现细节该值底层来自QWheelEvent::angleDelta()返回的QPoint包装层会先转成QPoint再取出x/y并转为int写入 JS 对象qwheelevent_wrap.cpp。像素增量 pixelDelta()pixelDelta(): { x: number; y: number }返回屏幕上滚动的像素距离。该值仅在支持高分辨率、基于像素的增量值的平台上提供例如 macOS应被直接用于滚动屏幕内容。⚠️平台限制在 X11Linux上该值取决于驱动不可靠应改用angleDelta()。实现上同样读取底层QPoint并返回{ x, y }数字对象qwheelevent_wrap.cpp。滚动相位 phase()phase(): ScrollPhase返回本次滚轮事件的滚动相位返回类型为ScrollPhase枚举定义于 ScrollPhase/index.ts枚举值数值含义NoScrollPhase0无滚动相位信息ScrollBegin1滚动开始ScrollUpdate2滚动更新中ScrollEnd3滚动结束ScrollMomentum4惯性滚动动量阶段需要注意Qt::ScrollBegin与Qt::ScrollEnd相位目前仅 macOS 支持见 QWheelEvent.ts 中的注释。C 侧直接static_castint(this-instance-phase())返回枚举整数值qwheelevent_wrap.cpp。是否反转 inverted()inverted(): boolean返回本次事件携带的 delta 值是否被反转。这对应操作系统或鼠标驱动中自然滚动Natural Scrolling之类的设置当系统将滚动方向反转时inverted()返回true。如果你的滚动逻辑需要与系统方向保持一致应在处理前检查该标志。鼠标按键 buttons()buttons(): number返回滚轮事件发生时按下的鼠标按键状态值为MouseButton组合位掩码来自 QSinglePointEvent。例如滚轮配合 Ctrl 键、或按住某键滚动时可通过该值与按键掩码做位运算判断。位置 position() 与全局位置 globalPosition()position(): { x: number; y: number } globalPosition(): { x: number; y: number }position()返回鼠标光标相对于接收事件的控件的位置注意该方法在 Qt 5.14 中才引入。若你在响应鼠标事件时移动了控件应改用globalPosition()。globalPosition()返回事件发生时鼠标指针的全局屏幕位置。在 X11 这类异步窗口系统上尤为重要当你在响应鼠标事件时移动控件globalPosition()与QCursor::pos()返回的当前光标位置可能差异很大。C 侧两者均读取QPointF并以qreal写入{ x, y }对象见 qsinglepointevent_macro.h。修饰键 modifiers()modifiers(): KeyboardModifier返回事件发生时的键盘修饰键组合类型为 KeyboardModifier 枚举枚举值十六进制值NoModifier0x00000000ShiftModifier0x02000000ControlModifier0x04000000AltModifier0x08000000MetaModifier0x10000000KeypadModifier0x20000000GroupSwitchModifier0x40000000C 侧将修饰键转为uint后作为数字返回qinputevent_macro.hJS 侧可直接与KeyboardModifier枚举做位与运算例如判断是否按住 Ctrl 滚轮缩放。时间戳 timestamp()timestamp(): number返回事件发生的时间戳继承自QInputEvent见 QInputEvent.ts。可用于计算两次滚轮事件的间隔、实现惯性效果或防抖。事件接受与传播控制以下方法继承自 QEvent方法签名说明accept()(): void设置事件的接受标志等价于setAccepted(true)。表示事件接收者想要该事件不被需要的事件会被传播给父控件。ignore()(): void清除事件的接受标志等价于setAccepted(false)。表示事件接收者不想要该事件事件可能被传播给父控件。setAccepted(accepted)(accepted: boolean): void显式设置事件的接受标志。isAccepted()(): boolean返回事件当前是否被接受。spontaneous()(): boolean返回事件是否源自应用外部系统事件Paint 事件此返回值未定义。type()(): number返回事件类型即QEvent::Type的整数值。C 实现集中在 qevent_macro.h 中。注意一个实现细节type()在原生层被重命名为_typeInstanceMethod(_type, ...)以避免与 JS 内建type冲突TypeScript 层 QEvent.ts 中type()实际调用的是this.native._type()。实战在 NodeGui 中监听滚轮事件事件名与枚举所有通用 QEvent 都收录在WidgetEventTypes枚举中滚轮事件对应的枚举值为WidgetEventTypes.Wheel定义于 EventWidget.ts原生映射表EventsMap::eventTypes中Wheel映射到QEvent::Wheeleventsmap.cpp。此外GraphicsSceneWheel对应QEvent::GraphicsSceneWheel可用于 QGraphicsScene 场景中的滚轮事件。完整示例滚动一个 QScrollArea 内容下面这段代码演示如何在任何EventWidget派生的控件如QLabel上监听滚轮事件读取增量并把内容卷起来const { QMainWindow, QWidget, QLabel, QScrollArea, QWheelEvent, WidgetEventTypes, } require(nodegui/nodegui); const win new QMainWindow(); win.resize(400, 300); const container new QWidget(); const label new QLabel(); label.setInlineStyle(min-height: 600px; background: #f2f2f2;); label.setText(滚动我试试); const scroll new QScrollArea(); scroll.setWidget(label); // 监听滚轮 QEvent scroll.addEventListener(WidgetEventTypes.Wheel, (nativeEvt) { const evt new QWheelEvent(nativeEvt); const { x, y } evt.angleDelta(); console.log(wheel angle delta:, x, y); console.log(pixel delta:, evt.pixelDelta()); console.log(phase:, evt.phase()); console.log(inverted:, evt.inverted()); console.log(global position:, evt.globalPosition()); console.log(modifiers:, evt.modifiers()); evt.accept(); // 明确接受该事件阻止继续向父控件传播 }); win.setCentralWidget(scroll); win.show(); global.win win;要点回顾回调的第一个参数是原生事件指针必须new QWheelEvent(nativeEvt)包装后才能调用 API角度增量与像素增量是只读的度量数据想真正滚动内容需要借助QScrollArea/QScrollBar等控件的原生滚动能力或手动更新布局在不需要父级继续处理时调用evt.accept()想让事件继续传播则调用evt.ignore()组合修饰键时用位运算判断例如(evt.modifiers() KeyboardModifier.ControlModifier) ! 0。处理高分辨率滚轮累积增量法针对细粒度滚轮增量 120可按文档建议实现增量累积达到一个标准刻度再滚动let accumulatedDelta 0; widget.addEventListener(WidgetEventTypes.Wheel, (nativeEvt) { const evt new QWheelEvent(nativeEvt); accumulatedDelta evt.angleDelta().y; // 120 单位 15 度一个标准刻度 while (accumulatedDelta 120) { // 滚动一个刻度例如让滚动条 value 步长 scrollBar.setValue(scrollBar.value() stepSize); accumulatedDelta - 120; } while (accumulatedDelta -120) { scrollBar.setValue(scrollBar.value() - stepSize); accumulatedDelta 120; } });在支持pixelDelta()的平台上如 macOS则直接使用像素值滚动即可获得更顺滑的原生手感而在 X11 上请坚持使用angleDelta()并注意其驱动相关性的局限。控制事件分发时机afterDefault 选项addEventListener支持EventListenerOptions其中的afterDefault决定回调在基类控件默认处理之前还是之后执行EventWidget.tswidget.addEventListener(WidgetEventTypes.Wheel, handler, { afterDefault: true });默认afterDefault: false回调先于基类控件的event()执行便于拦截与改写默认行为afterDefault: true回调在基类默认处理之后执行事件会以${eventType}_after名称分发EventWidget.ts适合做附加观察而不过度干预默认行为。相关源码速查想深入理解QWheelEvent的完整实现链路可按以下路径阅读类型定义与对外导出QWheelEvent.ts、index.ts事件基类QEventqevent_macro.h、QEvent.ts、QInputEventqinputevent_macro.h、QInputEvent.ts、QSinglePointEventqsinglepointevent_macro.h、QSinglePointEvent.tsC 包装与绑定qwheelevent_wrap.h、qwheelevent_wrap.cpp、main.cpp事件映射与分发eventsmap.cpp、eventwidget.cpp、EventWidget.ts相关枚举ScrollPhase、KeyboardModifier事件处理入门指南handle-events.md小结QWheelEvent是 NodeGui 中实现原生手感滚动体验的核心入口。通过本文你可以完整掌握它的继承体系QEvent → QInputEvent → QSinglePointEvent → QWheelEvent与各层方法来源angleDelta 的角度语义1/8 度单位、120 15 度、正负方向、pixelDelta 的平台限制macOS 可用、X11 不可靠phase / inverted / buttons / position / globalPosition / modifiers / timestamp等属性的精确含义与使用场景accept / ignore / setAccepted / isAccepted / spontaneous / type的事件传播控制手段结合WidgetEventTypes.Wheel与QWheelEvent构造器的完整监听范式以及高分辨率滚轮的累积增量处理策略。掌握了这些 API 与底层原理你就能在 NodeGui 桌面应用中写出流畅、方向正确、符合平台习惯的滚轮交互。赞分享桌面应用跨平台【免费下载链接】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 中 ScrollPhase 枚举详解通过 QWheelEvent 识别滚轮事件的滚动阶段NodeGui 中 ScrollPhase 枚举详解通过 QWheelEvent 识别滚轮事件的滚动阶段 NodeGui 的 ScrollPhase 枚举用于桌面应用跨平台Puppeteer 中 page.mouse.wheel() 详解模拟滚轮事件实现滚动与缩放Puppeteer 中 page.mouse.wheel 详解模拟滚轮事件实现滚动与缩放 导读 page.mouse.wheel 是 Puppeteer 在浏览器控制测试网页爬虫开发工具Textual MouseScrollRight 事件详解捕获终端横向滚轮滚动Textual MouseScrollRight 事件详解捕获终端横向滚轮滚动 导读 MouseScrollRight 是 Textual 事件体系中的一员前端UI组件异步编程上一篇Linux 内核 RCURead-Copy Update 核心概念、FAQ 与源码级实现剖析下一篇Bilidown如何安全下载B站8K超清视频这款工具给你答案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
倒装贴片与一般贴片工艺选型:从原理到实践 在消费电子、汽车电子、通信模块这些领域摸爬滚打这些年,几乎每个封装工程师都会遇到同一个灵魂拷问:手头这颗芯片,到底该走倒装贴片工艺(Flip Chip),还是老老实实用一般贴片工艺(Die Attach W… · 2026/9/25 3:54:23
备份的艺术:从3-2-1原则到人生备份档案馆 前阵子帮朋友抢救一台旧电脑,他没备份,十年的文件在一场系统崩溃里灰飞烟灭。他愣在原地的时候,我突然意识到——备份这个词,我以前也觉得特别无聊,直到前几天我把手机里十年的照片、聊天记录、备忘录,以及… · 2026/9/25 3:54:17
机器学习驱动学生综合能力测评:特征工程与模型落地实践 简介:一套基于机器学习的学生综合能力测试系统,面向教育信息化、智能测评与人工智能应用开发人员。项目以学情数据为依据,尝试将机器学习与深度学习引入学习评估,适合作为理解分类预测、特征工程、模型训练及前后端联动落地的实战… · 2026/9/25 3:54:17
如何正确引用arXiv论文:BibTeX模板、版本管理与常见错误 /* 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 4:26:51
USB转I2C适配器实现I2C地址扫描与100kHz时序测试 /* 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 4:26:51
APL文件分析实战:从结构解析到性能根因定位 /* 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 4:26:51
STM32芯片命名规则详解:从型号到选型实战指南 /* 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 4:26:51
北邮数据结构实验双路径:C手写栈与C++封装的工程实践 简介:本资源是北京邮电大学《数据结构与算法》课程的全套实验与作业实践材料,面向计算机及相关专业本科生、考研复习者及算法初学者,聚焦核心数据结构实现与经典算法动手训练。压缩包共43个文件,涵盖12个C源码(如单链表… · 2026/9/25 4:26:45
创维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