QGraphicsView父类中MouseMove和MouseButtonRelease事件获取办法

发布时间 2023-09-07 21:41:29作者: imxiangzi

QGraphicsView是QT支持的一套图元显示框架。最近在开发过程中发现一个问题,在QGraphicsView父类(QWidget)中重载mousePressEvent和 mouseMoveEvent事件,只能获取到mousePress事件,mouseMove事件不论如何都获取不到,测试代码如下,为了方便测试将布局的Margin设置成了20。发现在Margin区域所有鼠标事件是OK的,但是在QGraphicsView区域类,重载的两个事件只能获取到mousePress事件。

#include <QMouseEvent>

#include <QGraphicsView>

#include <QtWidgets>

 

GraphicsView::GraphicsView(QWidget *parent) : QWidget(parent)

{

    this->setMouseTracking(true);

 

    QGraphicsView* view = new QGraphicsView(this);

    view->setBackgroundBrush(QBrush(Qt::gray));

    view->setScene(new QGraphicsScene(view));

 

    QVBoxLayout* layout = new QVBoxLayout(this);

    layout->setMargin(20);

    layout->addWidget(view);

}

 

void GraphicsView::mousePressEvent(QMouseEvent *event)

{

    QWidget::mousePressEvent(event);

    qDebug() << "MouseButtonPress";

}

 

void GraphicsView::mouseMoveEvent(QMouseEvent *event)

{

    QWidget::mouseMoveEvent(event);

    qDebug() <<" MouseMove ";

}

遇到这个问题,于是猜想是否是QGraphicsView截断了鼠标事件,于是给QGraphicsView这个类安装了一个事件过滤器,用来截取鼠标事件,代码如下,发现效果与上述一致,并没有我们想象中的效果。

#include <QDebug>

#include <QMouseEvent>

#include <QGraphicsView>

#include <QtWidgets>

 

GraphicsView::GraphicsView(QWidget *parent) : QWidget(parent)

{

    this->setMouseTracking(true);

 

    QGraphicsView* view = new QGraphicsView(this);

    view->setBackgroundBrush(QBrush(Qt::gray));

    view->setScene(new QGraphicsScene(view));

 

    FilterObj* obj = new FilterObj(this);

    view->installEventFilter(obj);

 

    QVBoxLayout* layout = new QVBoxLayout(this);

    layout->setMargin(20);

    layout->addWidget(view);

}

 

bool FilterObj::eventFilter(QObject *obj, QEvent *event)

{

    if(event->type() == QEvent::MouseButtonPress){

        qDebug() << "MouseButtonPress";

    }else if(event->type() == QEvent::MouseMove){

        qDebug() <<" MouseMove ";

    }else if(event->type() == QEvent::MouseButtonRelease){

        qDebug() << "MouseButtonRelease";

    }

    return QObject::eventFilter(obj, event);

}

后查阅到https://zhuanlan.zhihu.com/p/31310711豁然开朗,原来鼠标事件是被QGraphicsView里面的viewport截取了,于是换最后一种实现方式问题解决,在viewport上安装一个事件过滤器,通过事件过滤来截取鼠标事件,实现鼠标事件的透传。

#include <QMouseEvent>

#include <QGraphicsView>

#include <QtWidgets>

 

GraphicsView::GraphicsView(QWidget *parent) : QWidget(parent)

{

    this->setMouseTracking(true);

 

    QGraphicsView* view = new QGraphicsView(this);

    view->setBackgroundBrush(QBrush(Qt::gray));

    view->setScene(new QGraphicsScene(view));

 

    FilterObj* obj = new FilterObj(this);

    view->setMouseTracking(true); //mouse move event occurred even if mouse is not pressed

    view->viewport()->installEventFilter(obj);

 

    QVBoxLayout* layout = new QVBoxLayout(this);

    layout->setMargin(20);

    layout->addWidget(view);

}

 

bool FilterObj::eventFilter(QObject *obj, QEvent *event)

{

    if(event->type() == QEvent::MouseButtonPress){

        qDebug() << "MouseButtonPress";

    }else if(event->type() == QEvent::MouseMove){

        qDebug() <<" MouseMove ";

    }else if(event->type() == QEvent::MouseButtonRelease){

        qDebug() << "MouseButtonRelease";

    }

    return QObject::eventFilter(obj, event);

}

 

 

from:https://blog.csdn.net/theoryll/article/details/110918779