Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Mouse press event not working, but mouse release event fires twice per click



  • Read the title. Take this code:

    MainWindow::MainWindow(QWidget *parent) : QWidget(parent) {
        qApp->installEventFilter(this);
    }
    bool MainWindow::eventFilter(QObject *obj, QEvent *event)
    {
      if (event->type() == QEvent::MouseButtonRelease)
      {
        std::cout << "Mouse Released" << std::endl;
      } else if (event->type() == QEvent::MouseButtonPress) {
        std::cout << "Mouse Pressed" << std::endl;
      }
            return false;
    }
    
    

    With MainWindow being any basic window UI, you'll see, in the output, "Mouse Released" two times, but no "Mouse Pressed". Any way I can fix this?


  • Moderators

    Hi, welcome to the forum.

    Any way I can fix this?

    It's not broken :)
    If you click twice in quick succession the events you get are:

    QEvent::MouseButtonPress
    QEvent::MouseButtonRelease
    QEvent::MouseButtonDblClick
    QEvent::MouseButtonRelease
    

    You're just not checking for the double click event.



  • This is happening when I click once. When I double click, it's released twice.

    And this still doesn't explain why the MouseButtonPress event isn't even being recognized...

    Even MouseButtonDblClick isn't released if I double click. I literally tried with mouse tracking on, what's going on?



  • @swirl
    You should be getting the events as shown by @Chris-Kawa. If you are not: first put in a case to report QEvent::MouseButtonDblClick as well, then test with single & double click, and copy & paste exactly what you get.



  • That for some reason fixed the issue with pressing not being registered, but now, it's STILL registering all the events twice. If I double click:

    Mouse Pressed
    Mouse Pressed
    Mouse Released
    Mouse Released
    Mouse Pressed
    Mouse Double Clicked
    Mouse Double Clicked
    Mouse Released
    Mouse Released
    

    Though oddly MouseButtonPress seems to be emitted only once when MouseButtonDblClick got emitted...

    On a potentially unrelated note, what would I do to recognize if a button is being pressed when the mouse is clicked? Or should I create a class extending off of QPushButton for that?


  • Moderators

    That's because you're installing the filter in the whole application, so you get that event for all the widgets it goes through.
    You can see it like this:

    bool MainWindow::eventFilter(QObject *obj, QEvent *evt)
    {
        switch(evt->type())
        {
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonDblClick:
        case QEvent::MouseButtonRelease:
            qDebug() << evt->type() << obj;
            break;
        }
        return false;
    }
    

    Install the filter only on the widget you want, for example main window, so just

    installEventFilter(this);
    

    without the qApp.


  • Moderators

    @swirl said:

    On a potentially unrelated note, what would I do to recognize if a button is being pressed when the mouse is clicked? Or should I create a class extending off of QPushButton for that?

    A "click" is a press and release on the same widget.
    "recognize if a button is being pressed when the mouse is clicked" doesn't make sense.
    What are you trying to do exactly?



  • I'm creating a little calculator-like UI and need a way for clicks to register on all buttons so I don't have to assign an event filter to literally all the buttons. As in, I need to know, in the event filter, which buttons are pressed.

    Plus, just using installEventFilter(this); breaks it, so it doesn't register any of the events..


  • Moderators

    Plus, just using installEventFilter(this); breaks it, so it doesn't register any of the events.

    Well if you want to filter events on all widgets then that's expected. In that case you'll have to check the object parameter of the event filter and only react to the objects you want to track.

    But honestly, this doesn't sound like something you should be doing through event filters at all. Why not simply connect to the button's clicked() signal? You could use single slot for them all. Qt even has a calculator example that does that.



  • @Chris-Kawa because... i need to display the button's text on a label? there's no QString param for clicked(), and I would need that or a custom signal. And this is literally the only way I could get it to work.

    And this still isn't explaining why the event filter is so messed up.



  • @swirl
    Why do you see " event filter is so messed up"? You would at least have to do as @Chris-Kawa said and debug out the obj parameter to see who the events are going to?



  • Have you checked out QSignalMapper? As the signal mapper documentation states though, it's somewhat obsolete and similar functionality can be achieved now with lambda slots (and has an example doing this).


  • Moderators

    @swirl said

    because... i need to display the button's text on a label? there's no QString param for clicked()

    You can do this with a lambda:

    for (auto button : allYourButtons)
    {
        connect(button, &QPushButton::clicked, [=]{ some_label->setText(button->text()); });
    }
    

    And this still isn't explaining why the event filter is so messed up.

    It's not messed up. It works as expected and I tried to explain it. For example if you have a MainWindow with a button in it you would get events like this:

    MouseButtonPress    //on the MainWindow's window
    MouseButtonPress    //on the button
    MouseButtonRelease  //on the MainWindow's window
    MouseButtonRelease  //on the button
    

    For a double click it will look like this:

    MouseButtonPress    //on the MainWindow's window
    MouseButtonPress    //on the button
    MouseButtonRelease  //on the MainWindow's window
    MouseButtonRelease  //on the button
    MouseButtonPress    //on the MainWindow's window, this time it gets interpreted as double click so it gets re-sent as a double click
    MouseButtonDblClick //on the MainWindow's window
    MouseButtonDblClick //on the button
    MouseButtonRelease  //on the MainWindow's window
    MouseButtonRelease  //on the button
    


  • @Chris-Kawa Seems to work. thankyou!


Log in to reply