关于QGraphicsView中重载的mouseMoveEvent失效的解决办法--通过事件过滤器来捕获鼠标事件,然后通过信号发送出去

QT版本:Qt_5.15.2

编译环境:MinGW 8.1.0 32 bit for C++

需要用QT写一个跨平台的软件,我使用的是Design直接拖拽的QGraphicsView,需要捕获鼠标在QGraphicsView范围内的移动事件。

在网上查了资料,结果基本都是重写mouseMoveEvent,但是我写了后,发现无法进入到对应的槽函数中。又在网上找资料,发现https://blog.csdn.net/theoryll/article/details/110918779   写得很好,总之一句话就是“鼠标事件被QGraphicsView里面的viewport截取了,需要通过在viewport上安装一个事件过滤器,通过事件过滤来截取鼠标事件,实现鼠标事件的透传”。

因此,为了方便自己后面使用,因此将事件过滤器单独写了一个类,在捕获到鼠标事件后,通过信号发送出去。

mouseeventfilter.h
#ifndef MOUSEFILTER_H
#define MOUSEFILTER_H

#include <QObject>
#include <QMouseEvent>

class QGraphicsView;

class MouseFilter : public QObject
{
    Q_OBJECT
public:
    explicit MouseFilter(QGraphicsView *view, QObject *parent = nullptr);

signals:
    void leftButtonClicked(QPointF pos);
    void rightButtonClicked(QPointF pos);
    void middleButtonClicked(QPointF pos);
    void wheelScrolled(QPoint delta);
    void mouseMoved(QPointF pos);

protected:
    bool eventFilter(QObject *watched, QEvent *event) override;

private:
    QGraphicsView *m_view;

};

#endif // MOUSEFILTER_H
///mouseeventfilter.cpp
#include "mouseeventfilter.h"
#include <QDebug>
#include <QGraphicsView>

MouseFilter::MouseFilter(QGraphicsView *view, QObject *parent)
    : QObject(parent),
      m_view(view)
{
    view->viewport()->installEventFilter(this);
}

bool MouseFilter::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == m_view->viewport()) {
        if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease ||
                event->type() == QEvent::MouseMove || event->type() == QEvent::Wheel) {

            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            //QPointF pos = m_view->mapToScene(mouseEvent->pos());
            QPointF pos(mouseEvent->pos());//将坐标转换成相对于左上角的坐标
            switch (mouseEvent->button()) {
            case Qt::LeftButton:
                if (event->type() == QEvent::MouseButtonPress) {
                    emit leftButtonClicked(pos);
                }
                break;
            case Qt::RightButton:
                if (event->type() == QEvent::MouseButtonPress) {
                    emit rightButtonClicked(pos);
                }
                break;
            case Qt::MiddleButton:
                if (event->type() == QEvent::MouseButtonPress) {
                    emit middleButtonClicked(pos);
                }
                break;
            default:
                break;
            }

            if (event->type() == QEvent::Wheel) {
                QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
                QPoint delta = wheelEvent->angleDelta();
                emit wheelScrolled(delta);
            }

            if (event->type() == QEvent::MouseMove) {
                emit mouseMoved(pos);
            }

            return true;
        }
    }

    return false;
}

在需要接收信号的类(一般是对话框或者widget)中,创建一个MouseFilter对象的成员变量

MouseFilter* m_MF_Start;

然后再构造函数中new一下

m_MF_Start=new MouseFilter(ui->graphicsView_Start,this);

然后在connect一下就行(槽函数及connect百度就行)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值