Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Proxy mouse/touch events
Forum Updated to NodeBB v4.3 + New Features

Proxy mouse/touch events

Scheduled Pinned Locked Moved QML and Qt Quick
1 Posts 1 Posters 1.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    zing0000
    wrote on 29 Jan 2015, 01:00 last edited by
    #1

    There has been some prior discussion, e.g.

    "fake events":http://stackoverflow.com/questions/18849663/generating-simulating-fake-mouse-events-in-qt

    but I am trying to get this working correctly with Qt5.4 and QQuickView. The simple project below demonstrates. A remote or proxy cursor moves within the main window and if it coincides with an UI element such as a button, a MouseEvent is generated that fakes a users action. The position of the proxy click can be anywhere but the event generated uses the position of the proxy cursor. So the button gets pressed.

    The ClickSimulator class creates an event and sends it to an UI element. This appears to work but the event is never received by the QML id realbutton.

    I am using prebuilt Qt5.4 and I am targeting multiple platforms. This is a genrally useful utility so I hope someone has done this and can spot some problem in my code.

    main.cpp
    @#include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQuickView>
    #include "clicksimulator.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    
    QQuickView *view = new QQuickView;
    view->setParent(window);
    
    // Setup the finger click handler
    ClickSimulator sim(window);
    sim.connect(window, SIGNAL(newfingerpos(int, int)),  SLOT(proxyClick(int, int)));
    QObject::connect(view->engine(), SIGNAL(quit()), view, SLOT(close()));
    
    return app.exec();
    

    }
    @

    main.qml
    @import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Window 2.2
    import QtQuick.Dialogs 1.2

    ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

    signal newfingerpos(int x, int y)
    
    // This is the overlay that catches the finger clicks
    Button {
        objectName: "overlaybutton"
        anchors.fill: parent
        opacity: 0.3
        z: 2
    
        MouseArea {
            anchors.fill: parent
            propagateComposedEvents: false
            onClicked: {
                mouse.accepted = true
                console.log("overlay tapped")
                newfingerpos(50, 50)
            }
        }
    }
    
    // This is the 'real' button but it will only be pressed from the newfingerpos signal
    Button {
        id: button
        objectName: "realbutton"
        width: 100; height: 100
        x:25; y:25
        text: qsTr("Press Me")
        z: 1
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                console.log("button pressed by proxy event")
                console.log("Mouse x: ", mouseX, "Mouse y: ", mouseY)
            }
        }
    }
    

    }
    @

    clicksimulator.h
    @#pragma once

    #include <QObject>
    #include <QQuickView>

    class ClickSimulator : public QObject
    {
    Q_OBJECT

    public:
    explicit ClickSimulator(QQuickWindow* viewer, QObject *parent = 0);

    public slots:
    void proxyClick(int, int);

    private:
    QQuickWindow* _viewport;

    };
    @

    clicksimulator.cpp
    @#include "clicksimulator.h"

    #include <QMouseEvent>
    #include <QQuickItem>

    ClickSimulator::ClickSimulator(QQuickWindow* viewport, QObject *parent) :
    QObject(parent),
    _viewport(viewport)
    {
    }

    void ClickSimulator::proxyClick(int x, int y)
    {
    if (_viewport != NULL) {
    QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(x, y), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    QQuickItem* controlarea = _viewport->findChild<QQuickItem*>("realbutton");
    const bool isSent = _viewport->sendEvent(controlarea, &pressEvent);
    qDebug() << "'Press' at (" << x << "," << y << ") successful? " << isSent;

        QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(x, y), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        const bool isRlseSent = _viewport->sendEvent(controlarea, &releaseEvent);
        qDebug() << "'Release' at (" << x << "," << y << ") successful? " << isRlseSent;
    
        _viewport->update();
    }
    

    }
    @

    mousetest.pro
    @TEMPLATE = app

    QT += qml quick widgets

    SOURCES += main.cpp
    clicksimulator.cpp

    RESOURCES += qml.qrc

    Additional import path used to resolve QML modules in Qt Creator's code model

    QML_IMPORT_PATH =

    Default rules for deployment.

    include(deployment.pri)

    HEADERS +=
    clicksimulator.h
    @

    1 Reply Last reply
    0

    1/1

    29 Jan 2015, 01:00

    • Login

    • Login or register to search.
    1 out of 1
    • First post
      1/1
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved