QWheelEvent 使用分析一例

13 篇文章 2 订阅

缘起

一网友问:

在VS里用Qt新建一个含mainwindow的项目,然后里面添加一个spinbox。除此之外啥都不做。
运行后,鼠标在spinbox内的时候,滚轮有效,移到spinbox外,无效。
在这种情况下,如何使滚轮在spinbox外对其有效?

答案其实很简单,QWheelEvent 的 Manual中如此描述(可是,你真的理解这句话了么?):

Wheel events are sent to the widget under the mouse cursor, but if that widget does not handle the event they are sent to the focus widget. 

一点弯路

说实话,这句话一开始我没有理解。相信大家也是一样,特别是,和它紧挨着还有这样一句话:

A wheel event contains a special accept flag that indicates whether the receiver wants the event. You should call ignore() if you do not handle the wheel event; this ensures that it will be sent to the parent widget.

看起来答案应该很明确,对吧?我们在派生类中override基类的wheelEvent(),然后对事件调用ignore()不就行了??

答案是:不行!!

事件转发?

我们在  Qt事件系统   一文中提到了事件转发,它描述的是这样一种情况:

+------------+
|     C      |
| +-------+  |
| |   B   |  |
| | +--+  |  |
| | |  |  |  |
| | | A|  |  |
| | +--+  |  |
| +-------+  |
+------------+

假定有父子关系的3个Widget:A、B、C(C是顶级窗口)。我们现在在 A 上点击鼠标:

  • 如果A没有接受该事件(ignore),那么事件将转发到B
  • 如果B依然没有接受,将转发到C
  • 即使C不接受,但由于已经是顶级窗口,事件也将停止传递。

所以,我们应该看清楚了:Manual中这个句子描述的是事件转发时的处理。

但前一节的那个句子不是事件转发。二者没有联系!!

WheelEvent

  Qt源码学习(从Win32到Qt)   一文中,我们举得就是Wheel Event的例子。它不属于我们前面提到的事件转发行为。

我们重新看看这段代码(它在窗口的回调函数中被调用,将系统的Wheel事件转换成Qt的Wheel事件,而后派发):

  • 首先是定位光标下的widget,将事件发送到该widget中(注意popup widget的处理)
  • 如果该widget不接受(sendSpontaneousEvent返回false)
    • 则查找当前拥有焦点的widget,让事件发送到该焦点widget

看到差别了吧:

 

要求

事件转发

返回true,但event被ignore

此处

返回false

注意:QWidget::event()的Manual中有些关于事件转发的介绍,请注意查看(此处略)。

如何解决?

答案至此已经很明确了:

  • 在wheelEvent()中,我们只能调用event的accept或ignore,这个只会影响到事件转发
  • 要影响返回值,我们必须override基类的 event() 函数让其返回false才行

一个完整的例子如下:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt 场景、视图、项应用实例,Qt整套源码,喜欢请下载: Link: #include <QGraphicsLineItem> class Node; class Link : public QGraphicsLineItem { public: Link(Node *formN, Node *toN); ~Link(); inline Node *formNode()const { return myFormNode; } inline Node *toNode() const { return myToNode; } void setColor(const QColor &c); QColor color()const; void trackNodes(); private: Node *myFormNode; Node *myToNode; }; Node: #ifndef NODE_H #define NODE_H #include <QGraphicsItem> #include <QSet> class Link; class Node : public QGraphicsItem { public: Node(); ~Node(); inline void setText(const QString &text;); inline QString text()const {return myText;} inline void setTextColor(const QColor &c) { myTextColor = c; update();} inline QColor textColor()const{return myTextColor;} inline void setBackgroundColor(const QColor &c) { myBackgroundColor = c; update();} inline QColor backgroundColor()const{return myBackgroundColor;} inline void setOutLineColor(const QColor &c) { myOutLineColor = c; update();} inline QColor outLineColor()const{return myOutLineColor;} void addLink(Link *l); void removeLink(Link *l); QRectF boundingRect()const Q_DECL_OVERRIDE; QPainterPath shape() const Q_DECL_OVERRIDE; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE; protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; QVariant itemChange(GraphicsItemChange change, const QVariant &value;) Q_DECL_OVERRIDE; private: QRectF outlineRect()const; int roundness(double size)const;//计算圆角 QSet<Link *> myLinks; QString myText; QColor myTextColor; QColor myBackgroundColor; QColor myOutLineColor; }; #endif // NODE_H View: #ifndef GRAPHICSVIEW_H #define GRAPHICSVIEW_H #include <QWidget> #include <QGraphicsView> #include <QGraphicsScene> class GraphicsView : public QGraphicsView { Q_OBJECT public: explicit GraphicsView(QGraphicsScene *scene, QWidget *parent = 0); protected: void wheelEvent(QWheelEvent *e); }; #endif // GRAPHICSVIEW_H
### 回答1: QtQWheelEvent是用于处理鼠标滚轮事件的类。它包含了滚动方向、滚动距离等信息。 QWheelEvent使用步骤如下: 1.在需要处理鼠标滚轮事件的部件重写wheelEvent函数。 2.在wheelEvent函数判断事件类型是否为QWheelEvent。 3.调用QWheelEvent的成员函数delta()获取滚动距离,正值表示向前滚动,负值表示向后滚动。 4.根据滚动距离进行相应的操作。 以下是一个简单的例子: ```cpp void MyWidget::wheelEvent(QWheelEvent *event) { if (event->type() == QEvent::Wheel) { // 判断事件类型是否为QWheelEvent int delta = event->delta(); // 获取滚动距离 if (delta > 0) { // 向前滚动 // 进行相应的操作 } else { // 向后滚动 // 进行相应的操作 } event->accept(); // 接受事件 } } ``` 需要注意的是,如果不调用event->accept()接受事件,那么滚轮事件将会被忽略。 ### 回答2: qtqwheelevent是一个用于处理鼠标滚轮事件的函数。当用户滚动鼠标滚轮时,系统会生成一个QWheelEvent对象并将其传递给相应的QWidget或QGraphicsView的event函数。我们可以在QWidget或QGraphicsView的子类重新实现该函数以自定义滚轮事件的处理方式。 QWheelEvent类提供了一些方法来获取和设置与滚轮事件相关的信息。可以使用方法angleDelta()获取滚动的角度,正数表示向前滚动,负数表示向后滚动。也可以使用方法pixelDelta()获取滚动的像素偏移量,其水平滚动偏移量通过x()方法获取,垂直滚动偏移量通过y()方法获取。此外,还可以使用方法modifiers()获取滚轮事件发生时的修饰键状态,如Shift、Ctrl和Alt等。 在重新实现qwheelevent时,我们可以根据需要进行特定的处理。例如,可以根据滚动方向调整窗口的缩放级别或滚动视图内容,也可以根据滚轮的角度或像素偏移量进行其他自定义操作。通常,我们会在重新实现的qwheelevent函数进行判断,以便根据滚动事件的类型进行不同的处理。要注意的是,为了确保事件被正确处理,有时候还需要调用父类的qwheelevent函数。 总而言之,qwheelevent是用于处理鼠标滚轮事件的函数,可以通过重新实现该函数来自定义滚轮事件的处理方式。可以使用QWheelEvent类的方法来获取和设置与滚轮事件相关的信息,从而根据需要进行相应的处理。 ### 回答3: 在QtQWheelEvent是鼠标滚轮事件类,用于响应鼠标滚轮的旋转操作。通过重写QWidget或QGraphicsView的wheelEvent()函数来处理该事件。 QWheelEvent类提供了一些有用的方法和属性,以便于处理滚轮事件。以下是一些常用的用法示例: 1. 获取滚轮旋转方向: 通过delta()方法可以获取滚轮的旋转方向,正值表示向前滚动,负值表示向后滚动。 2. 获取滚轮旋转的步数: 通过angleDelta()方法可以获取滚轮的旋转角度,单位为1/8度。可以根据该值来确定滚轮的旋转步数。 3. 设置滚轮事件的接受与否: 通过设置ignore()方法可以控制滚轮事件是否被忽略。将其设为false表示该事件将不会被忽略,而是会传递给其他控件进行处理。 4. 改变滚轮事件的默认行为: 可以通过重写wheelEvent()函数来改变滚轮事件的默认行为。比如按下Ctrl键时,滚轮事件可以具有不同的效果,如缩放窗口或改变画面大小等。 5. 控制滚轮事件的响应范围: 可以通过重写wheelEvent()函数的条件语句,来控制滚轮事件的响应范围。比如只有在特定的区域内滚动时才执行某些操作。 总之,QtQWheelEvent类提供了丰富的方法和属性,可以灵活地处理鼠标滚轮事件。通过重写相关函数或修改默认行为,可以实现各种滚轮操作,如缩放、滚动等,以达到更好的用户交互体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值