Qt5.13监听鼠标滚轮的上下滚动事件QWheelEvent的angleDelta().y()

There are two ways to read the wheel event delta: angleDelta() returns the delta in wheel degrees. This value is always provided. pixelDelta() returns the delta in screen pixels and is available on platforms that have high-resolution trackpads, such as macOS. If that is the case, source() will return Qt::MouseEventSynthesizedBySystem.

在Qt5中有两种读取鼠标滚轮事件滚动增量的方法:

  • angleDelta()返回滚轮度数的增量, 始终提供此值
  • pixelDelta()返回屏幕像素的增量,可以在具有高分辨率触摸板的平台上使用,比如macOS 如果是这样,source()将返回Qt::MouseEventSynthesizedBySystem,但在普通设备中source()将返回Qt::MouseEventNotSynthesized,并且pixelDelta()返回的是QPoint(0,0)
  • delta(),新版的Qt已经将其废除,它的返回值相当于angleDelta()的返回值的y点坐标

利用QWheelEvent的delta()函数获得滚轮滚动的距离值,通过此值判断滚轮滚动的方向。若delta大于0,则表示滚轮向前(远离用户的方向),小于零则表明向后,(靠近用户的方向)。
鼠标的滚动事件,滚轮每滚动1度,相当于移动了8度,而常见的滚轮鼠标拨动一下的滚动角度为15度,因此滚轮拨动一下相当于移动了120度。

void MainWindow::wheelEvent(QWheelEvent *event){
QPoint numPixels = event->pixelDelta();
    QPoint numDegrees = event->angleDelta();
    int delta = event->delta ();
    qDebug() << "numPixels:"<<numPixels;
    qDebug() << "numDegrees:"<<numDegrees;
    qDebug() << "delta:"<<delta;
    qDebug() << "the wheel event source: "<<event->source ();
    if(numDegrees.y()>0){
        qDebug() << "向前滚动"<<numDegrees.y();
    }else{
        qDebug() << "向后滚动"<<numDegrees.y();
    }
}

当上下滚动滑轮时,有如下显示:

numPixels: QPoint(0,0)
numDegrees: QPoint(0,120)
delta: 120
the wheel event source:  Qt::MouseEventNotSynthesized
向前滚动 120
numPixels: QPoint(0,0)
numDegrees: QPoint(0,-120)
delta: -120
the wheel event source:  Qt::MouseEventNotSynthesized
向后滚动 -120

综上所述,要判断鼠标滚轮滚动方向,可以使用QWheelEvent的delta()和angleDelta()函数,但是delta()函数在新版Qt中已被废除,所以最好使用angleDelta().y()的值来判断。

<think>我们已经在之前的讨论中详细说明了如何在Qt中处理鼠标滚轮事件,特别是与Ctrl键的组合操作。现在,用户询问的是“如何开启鼠标滚轮事件”。 实际上,在Qt中,鼠标滚轮事件QWheelEvent)默认是开启的,也就是说,只要你的控件继承了QWidget,它就会接收滚轮事件。但是,如果用户发现控件没有响应滚轮事件,可能是以下原因: 1. 控件本身没有实现wheelEvent()函数,并且没有将事件传递给父类(即没有调用父类的wheelEvent)。 2. 事件被其他控件截获(比如父控件处理了事件而没有传递下来)。 3. 控件被禁用(setEnabled(false))。 4. 控件设置了不接受鼠标事件(setAttribute(Qt::WA_TransparentForMouseEvents)或者setMouseTracking(false)等,但这些主要是针对鼠标移动事件)。 因此,“开启”鼠标滚轮事件实际上是指确保控件能够接收到并处理滚轮事件。通常,我们通过重写wheelEvent()函数来处理滚轮事件。 根据用户提供的引用[1],我们看到一种禁用滚轮事件的方法,即重写wheelEvent()并忽略事件(event->ignore())。反过来,如果我们想要启用滚轮事件,我们需要确保: - 控件是启用的(setEnabled(true))。 - 控件有焦点(如果必要的话,因为有些控件只在有焦点时响应滚轮)。 - 重写wheelEvent()函数并处理事件(如果需要自定义行为),或者确保父类实现能够处理(例如,QScrollArea会自动处理滚轮事件滚动)。 如果用户只是想让控件响应滚轮事件,而该控件原本就有滚轮事件的处理(比如QScrollArea内部的滚动),那么不需要额外操作。如果用户需要自定义行为,那么重写wheelEvent()即可。 另外,引用[2]给出了一个滚轮事件的简单示例,其中使用了event->delta(),但注意在较新的Qt版本中,推荐使用angleDelta()或pixelDelta()。 因此,回答如下: 在Qt中,鼠标滚轮事件默认是开启的。要使控件响应鼠标滚轮事件,只需重写控件的`wheelEvent(QWheelEvent *event)`函数,并在其中实现自定义的滚轮响应逻辑。如果不需要自定义行为,而是使用控件基类的滚轮事件处理(如QScrollArea的滚动),则无需重写。 步骤: 1. 创建一个自定义控件类(如继承自QWidget或任何Qt控件)。 2. 在类声明中重写`wheelEvent`函数。 3. 在实现中,根据滚轮事件的信息(如滚动的角度或像素偏移)执行相应的操作。 4. 如果希望事件在处理后不再传递给父控件,调用`event->accept()`;否则,调用`event->ignore()`让父控件继续处理。 示例代码(缩放视图): ```cpp #include <QWheelEvent> class CustomWidget : public QWidget { protected: void wheelEvent(QWheelEvent *event) override { // 获取滚轮滚动的角度增量(通常以8度为一个单位) QPoint angleDelta = event->angleDelta(); if (!angleDelta.isNull()) { // 通常我们只关心垂直滚动 int deltaY = angleDelta.y(); if (deltaY != 0) { // 根据滚动方向进行缩放 double scaleFactor = (deltaY > 0) ? 1.1 : 0.9; // 执行缩放操作... event->accept(); // 事件已处理 return; } } event->ignore(); // 未被处理,传递给父类 } }; ``` 注意事项: - 如果控件没有重写`wheelEvent`,那么它会将事件传递给父控件,直到某个控件处理它。如果没有任何控件处理,则事件被忽略。 - 对于某些复合控件(如QComboBox、QSpinBox等),它们内部已经处理了滚轮事件(例如改变数值)。如果想禁用这些控件的滚轮事件,可以参考引用[1]的方法,那么反过来,如果想让它们响应滚轮事件,则不要禁用(即不要重写并忽略事件,或者使用原有的控件)。 如果用户发现某个控件不响应滚轮事件,可以检查: 1. 控件是否被禁用(enabled属性)? 2. 是否有其他事件过滤器(eventFilter)截获了事件? 3. 是否该控件没有焦点?可以尝试设置焦点策略(setFocusPolicy)为Qt::StrongFocus。 另外,在QML中,可以通过MouseArea的onWheel信号处理器来处理滚轮事件。 生成相关问题: 1. 如何禁用Qt控件的鼠标滚轮事件? 2.Qt中,如何实现鼠标滚轮事件在多个控件之间的传递? 3. 如何确保控件在鼠标悬停时就能响应滚轮事件(而不需要焦点)? 注意:用户引用中提到了一个禁用滚轮事件的宏定义方法,我们在回答中也可以提到禁用与启用是相对的,禁用就是忽略事件,而启用就是处理事件。 </think>### Qt中开启鼠标滚轮事件的实现方法 在Qt中,鼠标滚轮事件默认是启用的。若控件未响应滚轮操作,通常需要重写`wheelEvent()`函数实现自定义处理。以下是具体实现步骤: #### 基础实现方法 1. **继承目标控件类** ```cpp class CustomWidget : public QWidget { // 可替换为QComboBox等控件 protected: void wheelEvent(QWheelEvent* event) override; }; ``` 2. **重写滚轮事件处理函数** ```cpp void CustomWidget::wheelEvent(QWheelEvent* event) { // 获取滚轮增量(兼容新旧Qt版本) const int delta = event->angleDelta().y(); if (delta > 0) { // 滚轮向上滚动处理 qDebug() << "Wheel up"; } else { // 滚轮向下滚动处理 qDebug() << "Wheel down"; } event->accept(); // 标记事件已处理 } ``` #### 启用特定控件的滚轮响应 对于组合框、微调框等控件: ```cpp // 继承并重写目标控件的滚轮事件 class CustomComboBox : public QComboBox { protected: void wheelEvent(QWheelEvent* event) override { // 自定义处理逻辑 event->accept(); // 启用滚轮事件 } }; ``` #### 启用滚轮事件的注意事项 1. **焦点策略设置** 确保控件可获取焦点: ```cpp widget->setFocusPolicy(Qt::StrongFocus); // 允许键盘和鼠标焦点 ``` 2. **事件传递机制** - 调用`event->accept()`阻止事件继续传递 - 调用`event->ignore()`允许父控件处理事件[^1] 3. **禁用默认滚轮行为** 某些控件(如QSpinBox)默认处理滚轮事件,如需完全自定义行为: ```cpp void CustomSpinBox::wheelEvent(QWheelEvent* event) { // 空实现 + accept = 完全禁用默认行为 event->accept(); } ``` #### 完整示例(文本缩放) ```cpp class ZoomableTextEdit : public QTextEdit { protected: void wheelEvent(QWheelEvent* event) override { if (event->modifiers() & Qt::ControlModifier) { const int delta = event->angleDelta().y(); zoomIn(delta > 0 ? 1 : -1); // 缩放文本 event->accept(); } else { QTextEdit::wheelEvent(event); // 保持默认滚动行为 } } }; ``` > **关键点**:Qt控件默认支持滚轮事件,重写`wheelEvent()`函数的主要目的是**定制响应逻辑**而非"开启"事件。对于已禁用滚轮的控件(如引用[1]的示例),只需移除`event->ignore()`调用即可恢复默认行为[^1]。
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值