Simulating mouse events for QML



  • Hi,

    I have a problem with sending mouse events to scene.

    Here is a simplified case:

    Let say I have a QML with rectangle and two MouseArea inside, I want MouseArea id:mA to simulate MousePress and MouseRelease events send to entire scene and processed by any component at x,y point of the event, in this case MouseArea id:mB.

    @
    Rectangle{
    width: 200
    height: 200

       MouseArea{
           id: mB
           x:0
           y:0
           width : parent.width/2
           height:parent.height
    
           onPressed:{
               // Do something
           }
       }
       MouseArea{
           id: mA
           x:parent.width/2
           y:0
           width : parent.width/2
           height:parent.height
    
           onPressed:{
               MySender.sendMousePressEvent(50,50)
           }
           onReleased:{
               MySender.sendMouseReleaseEvent(50,50)
           }
       }
    }
    

    @

    MySender is a class registered in main, where viewer is a QmlApplicationViewer with above QML loaded.:
    @
    MySender *s = new MySender (viewer.scene());
    viewer.rootContext()->setContextProperty("MySender ", (QObject *)s);
    @

    The MySender class itself contains the two methods that are supposed to send events
    @
    class MySender : public QObject
    {
    Q_OBJECT
    QGraphicsScene *target;

    public:
    MySender (QGraphicsScene *target)
    {
    this->target = target;
    }

    Q_INVOKABLE void sendMousePressEvent(int x,int y)
    {
    QPoint p0(x,y);
    QPoint p(0,0);
    QPoint pp = target->views()[0]->mapToGlobal(p0);
    //QWidget *w = QApplication::widgetAt(pp);
    //QMouseEvent bevent(QEvent::MouseButtonPress,p0,pp,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
    QGraphicsSceneMouseEvent bevent(QEvent::GraphicsSceneMousePress);
    bevent.setScenePos(p0);
    //bevent.setPos(p0);
    //bevent.setScreenPos(pp);
    bevent.setButton(Qt::LeftButton);
    bevent.setButtons(Qt::LeftButton);
    qDebug("Sending mouse press event %d, %d (%d,%d)",x,y,pp.x(),pp.y());
    if(!qApp->notify(target, &bevent))
    {
    qDebug("Mouse event not accepted by receiving widget.");
    }

     //qDebug("returned %d",QApplication::sendEvent(target,&bevent));
    

    }
    Q_INVOKABLE void sendMouseReleaseEvent(int x,int y)
    {
    QPoint p0(x,y);
    QPoint p(0,0);
    QPoint pp = target->views()[0]->mapToGlobal(p0);
    //QMouseEvent bevent(QEvent::MouseButtonPress,p0,pp,Qt::LeftButton,Qt::LeftButton,Qt::NoModifier);
    QGraphicsSceneMouseEvent bevent(QEvent::GraphicsSceneMouseRelease);
    bevent.setScenePos(p0);
    //bevent.setPos(p0);
    bevent.setButton(Qt::LeftButton);
    bevent.setButtons(Qt::LeftButton);
    qDebug("Sending mouse release event %d, %d (%d,%d)",x,y,pp.x(),pp.y());
    if(!qApp->notify(target, &bevent))
    {
    qDebug("Mouse event not accepted by receiving widget.");
    }
    //qDebug("returned %d",QApplication::sendEvent(target,&bevent));
    }
    };
    @

    As you can see, I have tried few things but it never hits breakpoint in MouseArea id:mB onPressed.

    Any idea what I did wrong? Please help!



  • I have figured out that the event does not get to MouseArea id:mB because of mouseGrabberItems() existing in QGraphicScene.

    An item becomes a mouse grabber when it receives and accepts a mouse press event, and it stays the mouse grabber until either of the following events occur:

    • If the item receives a mouse release event when there are no other buttons pressed, it loses the mouse grab.
    • If the item becomes invisible (i.e., someone calls item->setVisible(false)), or if it becomes disabled (i.e., someone calls item->setEnabled(false)), it loses the mouse grab.
    • If the item is removed from the scene, it loses the mouse grab.

    I have no clue how to workaround this :(



  • Actually I have the same problem than you. That is so weird specially in the removed Item I'm experimenting. The next Item is hoghlighted by the current index has value = -1



  • I have found out, that you can add mouse.accepted = false into event handlers, to propagate events to underneath items. This should work for basic events, but not for clicked or double clicked. To propagate these complex events, you have also add a property "propagateComposedEvents: true" to top most MouseArea.

    Now I have also compex event propagation work correctly, but somehow basic events do not want to propagate in my case.

    Actually I have two partially overlapping PathView-s. Top most PathView has its items moving along Path composed of PathArc, making available some space inside the arc. I have placed another PathView under that and it is perfectly fits inside.
    However the bottom PathView can only receive complex events propagated, so I cannot drag or flick objects in it. I also cannot change the Z order of PathView-s.

    Any suggestions?



  • Hi,
    I have the same issue.
    Seems this is a bug in Qt and no one cares about to fix it
    https://bugreports.qt.io/browse/QTBUG-37545



  • Hi,
    I have the same issue.
    Seems this is a bug in Qt and no one cares about to fix it
    https://bugreports.qt.io/browse/QTBUG-37545


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.