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百度就行)