@Pl45m4 Problem Solved
Re: qt C++: eventFilter does not see 'MouseMove' event
Thanks to everyone who contributed to solving this issue. In summary, I created a subclass of QGraphicsView (named MyQGrphicsView) to capture mouse press and mouse move events, and needed to use QGraphicsScene (instead of QGraphicsView) and the viewport.
I am providing the code below for a more detailed explanation. In this example, I used Qt Creator and created a QGraphicsView object in the main window, then promoted the object to MyQGraphicsView. When you run the example, a line is drawn in the window and when the mouse is pressed, released, or moved in the window the program outputs mouse information via qDebug. Here is the code.
MyGraphicsView.h:
#ifndef MYQGRAPHICSVIEW_H
#define MYQGRAPHICSVIEW_H
#include <QGraphicsView>
#include <QObject>
class MyQGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
MyQGraphicsView(QWidget *parent = nullptr);
~MyQGraphicsView();
bool eventFilter(QObject *object, QEvent *event);
public slots:
private:
QGraphicsScene *myScene;
int moveCount;
int pressCount;
int releaseCount;
};
#endif // MYQGRAPHICSVIEW_H
MyGraphicsView.cpp:
#include <QGraphicsSceneMouseEvent>
#include "myqgraphicsview.h"
MyQGraphicsView::MyQGraphicsView(QWidget *parent)
: QGraphicsView(parent)
{
myScene = new QGraphicsScene(this);
setScene(myScene); /* required in order to generate mouse events in myScene */
myScene->installEventFilter(this); /* required for eventFilter */
this->viewport()->setMouseTracking(true); /* required in order to generate GraphicsSceneMouseMove events */
moveCount = 0; /* for debugging */
pressCount = 0; /* for debugging */
releaseCount = 0; /* for debugging */
myScene->addLine(0, 100, 200, 200, Qt::SolidLine); /* (x1, y1, x2, y2, QPen) */
}
MyQGraphicsView::~MyQGraphicsView()
{
delete myScene; /* required since QGraphicsScene does not take ownership of myScene
(per QGraphicsScene::setScrene documentation) */
}
bool MyQGraphicsView::eventFilter(QObject *object, QEvent *event)
{
if (object == myScene){
// press event
if (event->type() == QEvent::GraphicsSceneMousePress)
{
const QGraphicsSceneMouseEvent* const me = static_cast<const QGraphicsSceneMouseEvent*>(event);
const QPoint position = me->scenePos().toPoint();
pressCount++;
qDebug("QEvent::GraphicsSceneMousePress %d, scene pos = %d, %d", pressCount, position.x(), position.y());
// your logic here
}
// release event
else if (event->type() == QEvent::GraphicsSceneMouseRelease)
{
const QGraphicsSceneMouseEvent* const me = static_cast<const QGraphicsSceneMouseEvent*>(event);
const QPoint position = me->scenePos().toPoint();
releaseCount++;
qDebug("QEvent::GraphicsSceneMouseRelease %d, scene pos = %d, %d", releaseCount, position.x(), position.y());
// your logic here
}
// move event
else if (event->type() == QEvent::GraphicsSceneMouseMove)
{
const QGraphicsSceneMouseEvent* const me = static_cast<const QGraphicsSceneMouseEvent*>(event);
const QPoint position = me->scenePos().toPoint();
moveCount++;
qDebug("QEvent::GraphicsSceneMouseMove count = %d, scene pos = %d, %d", moveCount, position.x(), position.y());
// your logic here
}
}
return QGraphicsView::eventFilter(object, event); /* pass-on the event to the base class QGraphicsView */
}
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
MainWindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="MyQGraphicsView" name="graphicsView">
<property name="geometry">
<rect>
<x>160</x>
<y>90</y>
<width>481</width>
<height>281</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>26</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>MyQGraphicsView</class>
<extends>QGraphicsView</extends>
<header location="global">MyQGraphicsView.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>