Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Struggling with mouse events
Qt 6.12 LTS is out! See what's new in the release blog

Struggling with mouse events

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 1.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    SteveFalco
    wrote on last edited by
    #1

    I am trying to catch both keyboard and mouse events. I am able to get both KeyPress and KeyRelease events, but I'm only able to get MouseButtonPress events. Something is eating the MouseButtonRelease events before I can see them.

    Below is a very stripped down app that shows the problem. I'm using QtCreator and I simply added a QGraphicsView, to which I attach the eventFilter.

    Interestingly, in the code below, if I comment out the ui->graphicsView->setScene(m_scene); line then I don't even get the MouseButtonPress events, but I still get the KeyPress and KeyRelease events.

    One last comment - if I change the else clause of the eventFilter to always return true instead of QObject::eventFilter(obj, event); then I do get both MouseButtonPress and MouseButtonRelease events, but the graphicsView doesn't work properly, because it is not getting its events.

    #include "map.h"
    #include "./ui_map.h"
    
    Map::Map(QWidget *parent)
    	: QMainWindow(parent), ui(new Ui::Map)
    {
    	ui->setupUi(this);
    
    	m_scene = new QGraphicsScene();
    	ui->graphicsView->setScene(m_scene);
    
    	ui->graphicsView->installEventFilter(this);
    }
    
    Map::~Map()
    {
    	delete ui;
    }
    
    bool
    Map::eventFilter(QObject *obj, QEvent *event)
    {
    	qInfo() << "event " << event;
    
    	if(event->type() == QEvent::KeyPress) {
    		QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    		qDebug("Ate key press %d", keyEvent->key());
    		return true;
    	} else if(event->type() == QEvent::KeyRelease) {
    		QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
    		qDebug("Ate key release %d", keyEvent->key());
    		return true;
    	} else if(event->type() == QEvent::MouseButtonPress) {
    		QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    		qDebug("Ate mouse press %d", mouseEvent->button());
    		return true;
    	} else if(event->type() == QEvent::MouseButtonRelease) {
    		QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    		qDebug("Ate mouse release %d", mouseEvent->button());
    		return true;
    	} else {
    		// standard event processing
    		return QObject::eventFilter(obj, event);
    	}
    }
    

    For completeness, here is the header file:

    #ifndef MAP_H
    #define MAP_H
    
    #include <QMainWindow>
    #include <QKeyEvent>
    #include <QMouseEvent>
    #include <QGraphicsScene>
    #include <QGraphicsView>
    
    QT_BEGIN_NAMESPACE
    namespace Ui {
    	class Map;
    }
    QT_END_NAMESPACE
    
    class Map : public QMainWindow
    {
    	Q_OBJECT
    
    	public:
    		explicit Map(QWidget *parent = nullptr);
    		~Map();
    
    	private:
    		Ui::Map *ui;
    
    		QGraphicsScene* m_scene;
    
    		bool eventFilter(QObject *obj, QEvent *event);
    };
    
    #endif // MAP_H
    

    And here is the ui file:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Map</class>
     <widget class="QMainWindow" name="Map">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>425</width>
        <height>824</height>
       </rect>
      </property>
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="sizeIncrement">
       <size>
        <width>0</width>
        <height>0</height>
       </size>
      </property>
      <property name="baseSize">
       <size>
        <width>0</width>
        <height>0</height>
       </size>
      </property>
      <property name="windowTitle">
       <string>Map</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QVBoxLayout" name="verticalLayout">
        <item>
         <widget class="QGraphicsView" name="graphicsView">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="alignment">
           <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>425</width>
         <height>23</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    Pl45m4P 1 Reply Last reply
    0
    • S SteveFalco

      I am trying to catch both keyboard and mouse events. I am able to get both KeyPress and KeyRelease events, but I'm only able to get MouseButtonPress events. Something is eating the MouseButtonRelease events before I can see them.

      Below is a very stripped down app that shows the problem. I'm using QtCreator and I simply added a QGraphicsView, to which I attach the eventFilter.

      Interestingly, in the code below, if I comment out the ui->graphicsView->setScene(m_scene); line then I don't even get the MouseButtonPress events, but I still get the KeyPress and KeyRelease events.

      One last comment - if I change the else clause of the eventFilter to always return true instead of QObject::eventFilter(obj, event); then I do get both MouseButtonPress and MouseButtonRelease events, but the graphicsView doesn't work properly, because it is not getting its events.

      #include "map.h"
      #include "./ui_map.h"
      
      Map::Map(QWidget *parent)
      	: QMainWindow(parent), ui(new Ui::Map)
      {
      	ui->setupUi(this);
      
      	m_scene = new QGraphicsScene();
      	ui->graphicsView->setScene(m_scene);
      
      	ui->graphicsView->installEventFilter(this);
      }
      
      Map::~Map()
      {
      	delete ui;
      }
      
      bool
      Map::eventFilter(QObject *obj, QEvent *event)
      {
      	qInfo() << "event " << event;
      
      	if(event->type() == QEvent::KeyPress) {
      		QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
      		qDebug("Ate key press %d", keyEvent->key());
      		return true;
      	} else if(event->type() == QEvent::KeyRelease) {
      		QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
      		qDebug("Ate key release %d", keyEvent->key());
      		return true;
      	} else if(event->type() == QEvent::MouseButtonPress) {
      		QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
      		qDebug("Ate mouse press %d", mouseEvent->button());
      		return true;
      	} else if(event->type() == QEvent::MouseButtonRelease) {
      		QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
      		qDebug("Ate mouse release %d", mouseEvent->button());
      		return true;
      	} else {
      		// standard event processing
      		return QObject::eventFilter(obj, event);
      	}
      }
      

      For completeness, here is the header file:

      #ifndef MAP_H
      #define MAP_H
      
      #include <QMainWindow>
      #include <QKeyEvent>
      #include <QMouseEvent>
      #include <QGraphicsScene>
      #include <QGraphicsView>
      
      QT_BEGIN_NAMESPACE
      namespace Ui {
      	class Map;
      }
      QT_END_NAMESPACE
      
      class Map : public QMainWindow
      {
      	Q_OBJECT
      
      	public:
      		explicit Map(QWidget *parent = nullptr);
      		~Map();
      
      	private:
      		Ui::Map *ui;
      
      		QGraphicsScene* m_scene;
      
      		bool eventFilter(QObject *obj, QEvent *event);
      };
      
      #endif // MAP_H
      

      And here is the ui file:

      <?xml version="1.0" encoding="UTF-8"?>
      <ui version="4.0">
       <class>Map</class>
       <widget class="QMainWindow" name="Map">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>0</y>
          <width>425</width>
          <height>824</height>
         </rect>
        </property>
        <property name="sizePolicy">
         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="sizeIncrement">
         <size>
          <width>0</width>
          <height>0</height>
         </size>
        </property>
        <property name="baseSize">
         <size>
          <width>0</width>
          <height>0</height>
         </size>
        </property>
        <property name="windowTitle">
         <string>Map</string>
        </property>
        <widget class="QWidget" name="centralwidget">
         <layout class="QVBoxLayout" name="verticalLayout">
          <item>
           <widget class="QGraphicsView" name="graphicsView">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="alignment">
             <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
            </property>
           </widget>
          </item>
         </layout>
        </widget>
        <widget class="QMenuBar" name="menubar">
         <property name="geometry">
          <rect>
           <x>0</x>
           <y>0</y>
           <width>425</width>
           <height>23</height>
          </rect>
         </property>
        </widget>
        <widget class="QStatusBar" name="statusbar"/>
       </widget>
       <resources/>
       <connections/>
      </ui>
      
      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @SteveFalco

      QGraphicsView doesn't like to propagate mouseEvents (I know there is something but cant remember the correct explanation right now).
      The better solution is to re-implement the mousePressEvent and mouseReleaseEvent in a QGraphicsView subclass directly.

      Edit:

      Btw, if you still want to stick to your solution, install the filter on the QGraphicsScene (not view), and catch like this:

              if(event->type() == QGraphicsSceneMouseEvent::GraphicsSceneMouseRelease) {
                  QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
                  qDebug("Ate Graphics mouse release %d", mouseEvent->button());
                  return false;  // or true, if you want to swallow the event here.
                                 // but this might cause unwanted behavior within the view/scene
              }
              if(event->type() == QGraphicsSceneMouseEvent::GraphicsSceneMousePress) {
                  QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
                  qDebug("Ate Graphics mouse press %d", mouseEvent->button());
                  return false; // same here
              }
      

      (Note the QGraphicsSceneMouseEvent-type)

      The normal key event will also still work :)


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      S 1 Reply Last reply
      1
      • Pl45m4P Pl45m4

        @SteveFalco

        QGraphicsView doesn't like to propagate mouseEvents (I know there is something but cant remember the correct explanation right now).
        The better solution is to re-implement the mousePressEvent and mouseReleaseEvent in a QGraphicsView subclass directly.

        Edit:

        Btw, if you still want to stick to your solution, install the filter on the QGraphicsScene (not view), and catch like this:

                if(event->type() == QGraphicsSceneMouseEvent::GraphicsSceneMouseRelease) {
                    QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
                    qDebug("Ate Graphics mouse release %d", mouseEvent->button());
                    return false;  // or true, if you want to swallow the event here.
                                   // but this might cause unwanted behavior within the view/scene
                }
                if(event->type() == QGraphicsSceneMouseEvent::GraphicsSceneMousePress) {
                    QGraphicsSceneMouseEvent *mouseEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
                    qDebug("Ate Graphics mouse press %d", mouseEvent->button());
                    return false; // same here
                }
        

        (Note the QGraphicsSceneMouseEvent-type)

        The normal key event will also still work :)

        S Offline
        S Offline
        SteveFalco
        wrote on last edited by
        #3

        @Pl45m4 said in Struggling with mouse events:

        QGraphicsView subclass

        Installing the filter on the scene works perfectly. Thanks!

        1 Reply Last reply
        0
        • S SteveFalco has marked this topic as solved on

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt
        • Unsolved