Why single mouse movement cause multiple event occurred
-
Here is a simple project for windows that trying to implement the simple dragging animation.
But when it run, the widget won't be dragged by the mouse. It looks like it translate the position to the cursor for a short time but translate back to its original position.
Look into the debug.txt, the event was sent multiple time about every move of the cursor, one occurred before the widget was moved and one after that moving. The first event's position info is about the old position of the widget but the second event's position info is about the new position of the widget. So the result is the widget was moved back to its original position by the second event process.
Although I got a solution about this "multiple event occurred" is using global position information of the event, i.e. ,ev->x() ev->y() ev->pos() // change those to ev->globalX() ev->globalY() ev->globalPos()
I was wander why a single mouse movement will cause multiple event to occurred.
Hope I can get an answer about this question.#include "customwidget.h" #include <QApplication> #include <QMainWindow> int main(int argc, char *argv[]) { QApplication a(argc, argv); // generate simple main window. QMainWindow w; // set the size of the window. w.setGeometry(0, 0, 800, 800); // generate the CustomWidget CustomWidget *widget = new CustomWidget(&w); // display the window containing the widget w.show(); return a.exec(); }
main.cpp
#ifndef CUSTOMWIDGET_H #define CUSTOMWIDGET_H #include <QWidget> #include <fstream> class CustomWidget : public QWidget { Q_OBJECT public: explicit CustomWidget(QWidget *parent = nullptr); ~CustomWidget(); protected: // define the painting agorithm to see the area of this widget void paintEvent(QPaintEvent* ev); // handle the pressing event to initialize the dragging algorithm // and to track the start of moving event void mousePressEvent(QMouseEvent* ev); // implement the dragging algorithm void mouseMoveEvent(QMouseEvent* ev); // handle the releasing event to track the end of moving event void mouseReleaseEvent(QMouseEvent* ev); private: std::ofstream fout; // open file "debug.txt" QPoint prev; // to save the previous point of cursor. }; #endif // CUSTOMWIDGET_H
customwidget.cpp
#include "customwidget.h" #include <QMouseEvent> #include <QPaintEvent> #include <QPainter> #include <QBrush> CustomWidget::CustomWidget(QWidget *parent) : QWidget(parent) { // open file for output fout.open("debug.txt"); // set the widget size and position setGeometry(0, 0, 100, 100); } CustomWidget::~CustomWidget() { // close file when program ended fout.close(); } void CustomWidget::paintEvent(QPaintEvent *ev) { // draw the area with blue color QPainter painter(this); QBrush brush(Qt::GlobalColor::blue); painter.setBrush(brush); painter.setBackground(brush); painter.drawRect(ev->rect()); } void CustomWidget::mousePressEvent(QMouseEvent *ev) { ev->accept(); // debug output fout << "pressed at (" << ev->x() << ',' << ev->y() << ") current mouse (" << ev->globalX() << ',' << ev->globalY() << ')' << std::endl; // initialize the dragging start point prev = ev->pos(); } void CustomWidget::mouseMoveEvent(QMouseEvent *ev) { ev->accept(); // get the cursor position of this event const QPoint& pos = ev->pos(); // debug output fout << "moved from (" << prev.x() << ',' << prev.y() << ") to (" << pos.x() << ',' << pos.y() << ") current mouse (" << ev->globalX() << ',' << ev->globalY() << ')' << std::endl; // calculate the cursor movement int dx = pos.x() - prev.x(); int dy = pos.y() - prev.y(); // move the widget position to match the direction of the cursor. move(geometry().x() + dx, geometry().y() + dy); // update the cursor position for the next event prev = pos; } void CustomWidget::mouseReleaseEvent(QMouseEvent *ev) { ev->accept(); fout << "released at (" << ev->x() << ',' << ev->y() << ") current mouse (" << ev->globalX() << ',' << ev->globalY() << ')' << std::endl; }
customwidget.h
pressed at (61,61) current mouse (69,92) moved from (61,61) to (61,61) current mouse (69,92) moved from (61,61) to (61,59) current mouse (69,90) moved from (61,59) to (61,61) current mouse (69,90) released at (61,59) current mouse (69,90)
debug.txt
Edited:
Include the current mouse global position output inside debug.txt.
As you can see the same position sent two event to the widget. -
Hi and welcome to devnet,
What OS are you on ?
You might want to use a minimal distance before considering that the movement is valid. See the drag and drop examples.
The mouse sensitivity can partly explain why you see several events.
-
I'm using Windows 10.
Its hard to believe the event manager didn't do that for me, but I did some test without using mouse to move the cursor the result is only receive only one movement event.
So you are right, I have to do the movement validate process before processing the event.
Thanks for the help! -
Do you mean native events ?
-
QAbstractNativeEventFilter might be of interest.
-
QAbstractNativeEventFilter might be of interest.