Solved 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? -
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 reportQEvent::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?
-
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
. -
@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.. -
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 theobj
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).
-
@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!