Results 1 to 7 of 7

Thread: Synthetic mouse events got "stuck" at position of firstly generated event

  1. #1

    Default Synthetic mouse events got "stuck" at position of firstly generated event

    Hi all,

    I'm trying to generate mouse events using QGuiApplication:ostEvent() and pass them to a QML scene. While the first event is processed correctly, following events are somehow stuck at the position of the first event. For example assume there are two MouseAreas left and right. When the first event is created inside the left MouseArea, onPressed() and onReleased() of this area are triggered. When the next event is created inside the right MouseArea, still the onPressed() and onReleased() of the left MouseArea are triggered. If I create an event with a real mouse the event occurs on the position of the last synthetic event. Anyhow, (solely) the next synthetic event is correct again. Also, after redrawing the window the next synthetic event is correct.

    Besides postEvent() I tried sendEvent() and notify() in combination with flush(), sendPostedEvents() and sync() (although the events seem to be delivered - just at the wrong position). I also send the events to a receiver class derived from QObject with an overridden event() method: the coords of the events were correct.

    Here is some sample code implementing the setup described above. Mouse events are generated alternating left and right every 3s. After a press event, a release event is created 0.3s later. If a MouseArea is pressed it turns green otherwise it is red. Real mouse events or moving the mouse over the rects cause the next synthetic event to be at the correct position.

    mouseeventgenerator.h:
    Qt Code:
    1. #ifndef MOUSEEVENTGENERATOR_H
    2. #define MOUSEEVENTGENERATOR_H
    3.  
    4. #include <QtCore>
    5.  
    6. class QQuickView;
    7.  
    8. class MouseEventGenerator : public QObject
    9. {
    10. Q_OBJECT
    11. public:
    12. explicit MouseEventGenerator(QQuickView *viewer = 0);
    13.  
    14. public slots:
    15. void generateMouseEvent();
    16. void generateReleaseEventLeft();
    17. void generateReleaseEventRight();
    18.  
    19. protected:
    20. void postEvent(int x, int y, int gesture_code);
    21.  
    22. QQuickView* m_viewer;
    23. QString m_lastSide;
    24. };
    25.  
    26. #endif // MOUSEEVENTGENERATOR_H
    To copy to clipboard, switch view to plain text mode 

    mousegenerator.cpp:
    Qt Code:
    1. #include "mouseeventgenerator.h"
    2. #include <QtCore>
    3. #include <QGuiApplication>
    4. #include <QApplication>
    5. #include <QtQuick/QQuickView>
    6.  
    7. MouseEventGenerator::MouseEventGenerator(QQuickView *viewer)
    8. : QObject(),
    9. m_viewer(viewer),
    10. m_lastSide("")
    11. {
    12. QTimer *timer = new QTimer(this);
    13. connect(timer, SIGNAL(timeout()), this, SLOT(generateMouseEvent()));
    14. timer->start(3000);
    15. }
    16.  
    17. void MouseEventGenerator::generateMouseEvent(){
    18. if(m_lastSide == "right"){
    19. postEvent(220, 220, 1);
    20. QTimer::singleShot(300, this, SLOT(generateReleaseEventLeft()));
    21. m_lastSide = "left";
    22. }else{
    23. postEvent(420, 220, 1);
    24. QTimer::singleShot(300, this, SLOT(generateReleaseEventRight()));
    25. m_lastSide = "right";
    26. }
    27. }
    28.  
    29. void MouseEventGenerator::generateReleaseEventLeft(){
    30. postEvent(220, 220, 0);
    31. }
    32.  
    33. void MouseEventGenerator::generateReleaseEventRight(){
    34. postEvent(420, 220, 0);
    35. }
    36.  
    37. void MouseEventGenerator::postEvent(int x, int y, int gesture_code){
    38. if(gesture_code == 1){
    39. QMouseEvent *pressEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(x, y),
    40. Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    41. QGuiApplication::postEvent(m_viewer, pressEvent);
    42. }
    43. else if(gesture_code == 0){
    44. QMouseEvent *releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease, QPoint(x,y),
    45. Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    46. QGuiApplication::postEvent(m_viewer, releaseEvent);
    47. }
    48. }
    To copy to clipboard, switch view to plain text mode 

    main.qml:
    Qt Code:
    1. import QtQuick 2.4
    2.  
    3. Item {
    4. width: 640
    5. height: 480
    6. visible: true
    7.  
    8. Rectangle {
    9. id: background
    10. anchors.fill: parent
    11. color: "black"
    12. }
    13.  
    14. Rectangle {
    15. id: rectLeft
    16. x: 200
    17. y: 200
    18. width: 100; height: 100
    19. color: "red"
    20.  
    21. MouseArea {
    22. anchors.fill: parent
    23. onPressed: {
    24. parent.color = "green"
    25. }
    26. onReleased: {
    27. parent.color = "red"
    28. }
    29. }
    30. }
    31.  
    32. Rectangle {
    33. id: rectRight
    34. x: 400
    35. y: 200
    36. width: 100; height: 100
    37. color: "red"
    38.  
    39. MouseArea {
    40. anchors.fill: parent
    41.  
    42. onPressed: {
    43. parent.color = "green"
    44. }
    45. onReleased: {
    46. parent.color = "red"
    47. }
    48. }
    49. }
    50.  
    51. }
    To copy to clipboard, switch view to plain text mode 

    main.cpp:
    Qt Code:
    1. #include <QGuiApplication>
    2. #include <QtQuick/QQuickView>
    3. #include <QQmlContext>
    4. #include "mouseeventgenerator.h"
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QGuiApplication app(argc, argv);
    9. QQuickView view;
    10.  
    11. MouseEventGenerator *generator = new MouseEventGenerator(&view);
    12.  
    13. view.setResizeMode(QQuickView::SizeRootObjectToView);
    14. view.setSource(QUrl("qrc:/main.qml"));
    15. view.show();
    16.  
    17. return app.exec();
    18. }
    To copy to clipboard, switch view to plain text mode 

    Any help is highly appreciated!

    Cheers,
    Thomas

    PS: I'm using Qt 5.4.2 and gcc 5.1.
    PPS: Maybe this is somehow connected? [URL="http://http://www.qtcentre.org/threads/61989-Stop-mouse-event-and-start-on-another-widget"]

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Synthetic mouse events got "stuck" at position of firstly generated event

    Maybe you need move events?

    Cheers,
    _

  3. #3

    Default Re: Synthetic mouse events got "stuck" at position of firstly generated event

    Thanks for the suggestion. I tried adding move events after each press and release event – to no avail.

    But somehow you could be right. I examined the mouse.x and mouse.y properties for the MouseArea:nPressed(). They are relative to the receiving item. For the synthetic events they also seem to be relative to the first item that was clicked(?). For example:

    qml: PRESSED MouseArea RIGHT: 20::20 <-- simulated press event in the right MouseArea
    qml: PRESSED MouseArea RIGHT: -180::20 <-- simulated press event in the left MouseArea

    In this case all events are received by the right MouseArea as if there is some kind of active focus for mouse events. Subsequently, I examined the MouseArea::entered() and exited() signals which seemed to be send correctly (press event --> onEntered triggered, release event --> onExited triggered).

    Thanks for any clue,
    Thomas
    Last edited by yurumi; 21st August 2015 at 13:23.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Synthetic mouse events got "stuck" at position of firstly generated event

    You can install an event filter on the application object, it will "see" all events that happen in the application.

    Cheers,
    _

  5. #5

    Default Re: Synthetic mouse events got "stuck" at position of firstly generated event

    Thanks for the quick reply! In fact you were so fast that you overtook me while I was editing my previous post (please have a look above).

    In the meantime I installed a custom event filter and compared the real mouse movement events with my generated events. The only differences for the real input are quite alot of MouseMove events and some CursorChange events when the mouse passes the MouseAreas/Rects. I recreated the MouseMove events more sophisticated, so that there is a trail of events from/to the origin before/after each press/release event. I even created CursorChange events everytime the origin is reached. Still doesn't work :-(

    When comparing the real mouse movement with the simulated one, there is another difference: When the simulated move events enter/exit the MouseArea which was previously clicked, onEntered() / onExited() are triggered (not so for the other MouseArea). This also suggests that there is some kind of unreleased focus. I stumbled upon grabMouse() and releaseMouse() for QWidget. The pendant for QQuickItems seems to be ungrabMouse(). I tried creating QEvent::UngrabMouse events which somehow sounds promising. Also no luck

    Maybe it would be better to create QTouchEvent, but this seems to be quite difficult: https://forum.qt.io/topic/46140/gene...ate-touches/12

  6. #6

    Default Re: Synthetic mouse events got "stuck" at position of firstly generated event

    ...just to close this topic: Although not fully satisfying, I figured out a workaround for the above mentioned problem.

    For every MouseArea add:
    Qt Code:
    1. ...
    2. onReleased: {
    3. ...
    4. parent.visible = false
    5. parent.visible = true
    6. }
    To copy to clipboard, switch view to plain text mode 
    so the mouse event somehow gets "reset"...

  7. #7
    Join Date
    Dec 2015
    Posts
    5
    Thanked 1 Time in 1 Post

    Default Re: Synthetic mouse events got "stuck" at position of firstly generated event

    I've found that you can get the item that grabbed the mouse via QQuickWindow::mouseGrabberItem(). Then you have to do the bound checking and call QQuickItem::ungrabMouse() when needed.

    It's probably somehow related to the implementation of dragging.

  8. The following user says thank you to velorums for this useful post:

    anda_skoa (30th December 2015)

Similar Threads

  1. Replies: 3
    Last Post: 7th August 2015, 12:37
  2. Replies: 1
    Last Post: 12th October 2010, 14:43
  3. Replies: 4
    Last Post: 18th April 2010, 00:37
  4. Translation QFileDialog standart buttons ("Open"/"Save"/"Cancel")
    By victor.yacovlev in forum Qt Programming
    Replies: 4
    Last Post: 24th January 2008, 19:05
  5. Replies: 7
    Last Post: 20th November 2007, 12:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.