Changing QMouseEvent position
-
Hello,
I feel this subject might be already solved, but I did'nt find it, sorry...
I would like to change the position x-y of a QMouseEvent. (using Qt 5.11)
For example, when clicking at x=120 & y=120, I would like the 100x100 QPushButton located at 0 to receive the press event.
For the moment, I override event from a MainWindow class :bool MainWindow::event(QEvent *event) { if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); qDebug() << "Mouse event detected (" << event->type() << ")- x=" << mouseEvent->x() << " - y=" << mouseEvent->y() ; // I tried this but it does'nt change anything const QPoint newPos(mouseEvent->x() - 50, mouseEvent->y() - 50); mouseEvent->setLocalPos(newPos); return true; } else { // pass the event on to the parent class return QMainWindow::event(event); } }
But this doesn't prevent the event to be located at (120,120)...
I feel I am on the wrong direction.
Any help would be greatly appreciated !
Thank you !Etienne
-
Hi
Can you explain a bit what is the use case for this ?
It sounds a bit strange so not sure i understand. :)So you have a windows MainWindow with a button on, and in case you click some where else on the MainWindow
you want the button to get the MouseButtonPress anyway ?
Regardless of where you click ?You could use
http://doc.qt.io/qt-5/qwidget.html#grabMouse
and all mouse events go to button until you release it but im not sure
that is what you want. -
Hi,
I think you need to send a mouse press event yourself.
But it seems there's more simple :[slot] void QAbstractButton::click()
Performs a click.
All the usual signals associated with a click are emitted as appropriate. If the button is checkable, the state of the button is toggled. -
Thank you for you replies !
The idea behind is a plan B in case I do not succeed in calibrating my touchscreen with my screen (sizes are different).
So I need to catch all mouse's events in my app, perform a transformation for each (the calibration) and send new events with a different position. I although need catch events to be ignored by my app which should only received "calibrated events".
My app contains different buttons and pages, so I would need something generic.@mpergand : When you say I think you need to send a mouse press event yourself, do you know how I can first make them ignored by all my QPushButton in my app ? That would be a nice first step ! After that, I may use this
bool QCoreApplication::sendEvent(QObject * receiver, QEvent * event)
to send my custom event
Thank you for helping !
-
Thank you for you replies !
The idea behind is a plan B in case I do not succeed in calibrating my touchscreen with my screen (sizes are different).
So I need to catch all mouse's events in my app, perform a transformation for each (the calibration) and send new events with a different position. I although need catch events to be ignored by my app which should only received "calibrated events".
My app contains different buttons and pages, so I would need something generic.@mpergand : When you say I think you need to send a mouse press event yourself, do you know how I can first make them ignored by all my QPushButton in my app ? That would be a nice first step ! After that, I may use this
bool QCoreApplication::sendEvent(QObject * receiver, QEvent * event)
to send my custom event
Thank you for helping !
@etiennedm
Hi
Ah, make more sense now.
I really hope you can calibrate the screen.Anyway, i think overriding
http://doc.qt.io/qt-5/qcoreapplication.html#notify
would allow this - as this function will see any event before distributed. -
@mrjj
Thanks for pointing that out !
I will look into this and try to make it work on a test example.@etiennedm
I think, you're on the right track for your situations.If you override the top most (mainWindow) Qwidget::event of your app you can calculate your offset position and detect transfer the event along via
QWidget::childAt
and
QCoreApplication::sendEvent
something along this
bool MainWindow::event(QEvent *event) { if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); const QPoint newPos(mouseEvent->x() - 50, mouseEvent->y() - 50); QWidget *w = childAt(newPos); if(w) return QCoreApplication::sendEvent(qObject_cast<QObject *>(w), event); else return true; } }
-
Thank you all ! Problem solved !
I used a custom class inherited from QApplication to override notify as suggested by @mrjj
I'm able to change the event before it is sent to the entire app, thanks !
Code here :bool MyQApplication::notify(QObject *receiver, QEvent *event) { if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); qDebug() << "Mouse event detected (" << event->type() << ")- x=" << mouseEvent->x() << " - y=" << mouseEvent->y(); const QPoint newPos(mouseEvent->x() - 50, mouseEvent->y() - 50); mouseEvent->setLocalPos(newPos); return QApplication::notify(receiver, mouseEvent); } else { return QApplication::notify(receiver, event); } }
Thanks,
Etienne
-
Thank you all ! Problem solved !
I used a custom class inherited from QApplication to override notify as suggested by @mrjj
I'm able to change the event before it is sent to the entire app, thanks !
Code here :bool MyQApplication::notify(QObject *receiver, QEvent *event) { if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); qDebug() << "Mouse event detected (" << event->type() << ")- x=" << mouseEvent->x() << " - y=" << mouseEvent->y(); const QPoint newPos(mouseEvent->x() - 50, mouseEvent->y() - 50); mouseEvent->setLocalPos(newPos); return QApplication::notify(receiver, mouseEvent); } else { return QApplication::notify(receiver, event); } }
Thanks,
Etienne
@etiennedm
great!But you'll have to modfy that code of yours a bit.
I don't think that it would- currently - change to other objects, if your touch event is at the border of 2 objects and the offset would push the event to the next one.I might be wrong, or it might also depend on the z-order of the widgets, I'm unsure.
-
@J-Hilk Thank for helping me on this.
Could you provide some details on what you're pointing out ?The test I ran seems to work well for me (maybe I mis-explained what I wanted to achieve), so when I click aside a button, I can "click" it adjusting the offset (overriding notify). When I click on it (native cursor on it), nothing happens. (as long as the offset is enough to go outside the button)
I have some code running (largely based on this) if you want.
Thanks !
Etienne
-
@J-Hilk Thank for helping me on this.
Could you provide some details on what you're pointing out ?The test I ran seems to work well for me (maybe I mis-explained what I wanted to achieve), so when I click aside a button, I can "click" it adjusting the offset (overriding notify). When I click on it (native cursor on it), nothing happens. (as long as the offset is enough to go outside the button)
I have some code running (largely based on this) if you want.
Thanks !
Etienne
@etiennedm
I'm more thinking along the following line.you have 2 QPushButtons next to each other, seperated by (let's say) 10 px. The left one goes a page back and the right one a pge forwards ( in example a QStackedWidget).
Now you have an offset of 50 in x direction.
Now you press the touch screen, your calculation pushes the new postion to the forwards button, but physically QCoreApplication registered the back button as receiver object.
As a result, your touchinput is ignored.