qt C++: eventFilter does not see 'MouseMove' event
-
I'm using Qt C++ 6.6.1 and Qt Creator 12.0.2 on Windows 11 for creating a desktop application. I have a QGraphicsView/QChartView object in a modal Dialog window for displaying line graphs. The Dialog::eventFilter looks like this:
bool Dialog::eventFilter(QObject *object, QEvent *event) { if (object->objectName() == "graphicsView") { if (event->type() == QEvent::MouseButtonPress) { qDebug("QEvent::MouseButtonPress, objectName = %s", qPrintable(object->objectName())); } else if (event->type() == QEvent::MouseMove) { qDebug("QEvent::MouseMove, objectName = %s", qPrintable(object->objectName())); } } // standard event processing return QObject::eventFilter(object, event); }When the program is executing, then I click the mouse in the graphisView and the qDebug message 'MouseButtonPress' is observed. However, if I just move the mouse in the graphicsView the qDebug message 'MouseMove' is NOT observed. Why is the eventFilter not seeing the 'MouseMove' event but is seeing the 'MouseButtonPress' event.
Here is the code that demonstrates the issue:
In the *.pro file I added 'charts' as follows:QT += core gui chartsmainwindow.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: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hdialog.h:
#ifndef DIALOG_H #define DIALOG_H #include <QChart> #include <QDialog> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); protected: bool eventFilter(QObject *object, QEvent *event) override; private slots: private: Ui::Dialog *ui; }; #endif // DIALOG_Hmain.cpp:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "dialog.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { Dialog myDialog; myDialog.setModal(true); myDialog.exec(); }diaglog.cpp:
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent) , ui(new Ui::Dialog) { ui->setupUi(this); ui->graphicsView->installEventFilter(this); ui->graphicsView->setMouseTracking(true); } Dialog::~Dialog() { delete ui; } bool Dialog::eventFilter(QObject *object, QEvent *event) { if (object->objectName() == "graphicsView") { if (event->type() == QEvent::MouseButtonPress) { qDebug("QEvent::MouseButtonPress, objectName = %s", qPrintable(object->objectName())); } else if (event->type() == QEvent::MouseMove) { qDebug("QEvent::MouseMove, objectName = %s", qPrintable(object->objectName())); } } // standard event processing return QObject::eventFilter(object, event); }dialog.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>822</width> <height>478</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QChartView" name="graphicsView"> <property name="geometry"> <rect> <x>160</x> <y>80</y> <width>481</width> <height>291</height> </rect> </property> </widget> </widget> <customwidgets> <customwidget> <class>QChartView</class> <extends>QGraphicsView</extends> <header>qcharts.h</header> </customwidget> </customwidgets> <resources/> <connections/> </ui>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="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>250</x> <y>200</y> <width>231</width> <height>29</height> </rect> </property> <property name="text"> <string>Open Dialog Window</string> </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> <resources/> <connections/> </ui> -
I'm using Qt C++ 6.6.1 and Qt Creator 12.0.2 on Windows 11 for creating a desktop application. I have a QGraphicsView/QChartView object in a modal Dialog window for displaying line graphs. The Dialog::eventFilter looks like this:
bool Dialog::eventFilter(QObject *object, QEvent *event) { if (object->objectName() == "graphicsView") { if (event->type() == QEvent::MouseButtonPress) { qDebug("QEvent::MouseButtonPress, objectName = %s", qPrintable(object->objectName())); } else if (event->type() == QEvent::MouseMove) { qDebug("QEvent::MouseMove, objectName = %s", qPrintable(object->objectName())); } } // standard event processing return QObject::eventFilter(object, event); }When the program is executing, then I click the mouse in the graphisView and the qDebug message 'MouseButtonPress' is observed. However, if I just move the mouse in the graphicsView the qDebug message 'MouseMove' is NOT observed. Why is the eventFilter not seeing the 'MouseMove' event but is seeing the 'MouseButtonPress' event.
Here is the code that demonstrates the issue:
In the *.pro file I added 'charts' as follows:QT += core gui chartsmainwindow.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: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hdialog.h:
#ifndef DIALOG_H #define DIALOG_H #include <QChart> #include <QDialog> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = nullptr); ~Dialog(); protected: bool eventFilter(QObject *object, QEvent *event) override; private slots: private: Ui::Dialog *ui; }; #endif // DIALOG_Hmain.cpp:
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "dialog.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { Dialog myDialog; myDialog.setModal(true); myDialog.exec(); }diaglog.cpp:
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent) , ui(new Ui::Dialog) { ui->setupUi(this); ui->graphicsView->installEventFilter(this); ui->graphicsView->setMouseTracking(true); } Dialog::~Dialog() { delete ui; } bool Dialog::eventFilter(QObject *object, QEvent *event) { if (object->objectName() == "graphicsView") { if (event->type() == QEvent::MouseButtonPress) { qDebug("QEvent::MouseButtonPress, objectName = %s", qPrintable(object->objectName())); } else if (event->type() == QEvent::MouseMove) { qDebug("QEvent::MouseMove, objectName = %s", qPrintable(object->objectName())); } } // standard event processing return QObject::eventFilter(object, event); }dialog.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>822</width> <height>478</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QChartView" name="graphicsView"> <property name="geometry"> <rect> <x>160</x> <y>80</y> <width>481</width> <height>291</height> </rect> </property> </widget> </widget> <customwidgets> <customwidget> <class>QChartView</class> <extends>QGraphicsView</extends> <header>qcharts.h</header> </customwidget> </customwidgets> <resources/> <connections/> </ui>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="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x>250</x> <y>200</y> <width>231</width> <height>29</height> </rect> </property> <property name="text"> <string>Open Dialog Window</string> </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> <resources/> <connections/> </ui>@EricR said in qt C++: eventFilter does not see 'MouseMove' event:
Why is the eventFilter not seeing the 'MouseMove' event
Documentation says:
Mouse move events will occur only when a mouse button is pressed down, unless mouse tracking has been enabled with QWidget::setMouseTracking(). -
@EricR said in qt C++: eventFilter does not see 'MouseMove' event:
Why is the eventFilter not seeing the 'MouseMove' event
Documentation says:
Mouse move events will occur only when a mouse button is pressed down, unless mouse tracking has been enabled with QWidget::setMouseTracking(). -
@mpergand Thanks for the quick reply. I called
ui->graphicsView->setMouseTracking(true);
In the Dialog constructor shown in the code snippet above. -
IIRC, you need to filter the
QGraphicsScenefor move events. Then they becomeQGraphicsSceneMouseEventsThere was a similar topic lately (couple month ago), but can't find it right now.
-
IIRC, you need to filter the
QGraphicsScenefor move events. Then they becomeQGraphicsSceneMouseEventsThere was a similar topic lately (couple month ago), but can't find it right now.
@Pl45m4 Problem Solved
Re: qt C++: eventFilter does not see 'MouseMove' eventThanks 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_HMyGraphicsView.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_HMainWindow.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> -
E EricR has marked this topic as solved on