Object to process touch event but also let it through

泪湿孤枕 提交于 2019-11-30 16:29:10

You can subclass QQuickItem and override the touchEvent() function:

This event handler can be reimplemented in a subclass to receive touch events for an item. The event information is provided by the event parameter.

You'll probably need to explicitly set accepted to false to ensure that the item doesn't steal the events:

Setting the accept parameter indicates that the event receiver wants the event. Unwanted events might be propagated to the parent widget. By default, isAccepted() is set to true, but don't rely on this as subclasses may choose to clear it in their constructor.


I can verify that the above will result in the lower touch area taking all events after the press (tested on an Android phone). In that case, you'll need to filter the events somehow. One way to do this is, inside your QQuickItem subclass, declare a property that will be used to point to the lower touch area. When that property changes, install an event filter on the touch area:

main.cpp:

#include <QGuiApplication>
#include <QtQuick>

class CustomTouchArea : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QQuickItem *targetTouchArea READ targetTouchArea WRITE setTargetTouchArea NOTIFY targetTouchAreaChanged)

public:
    CustomTouchArea() :
        mTargetTouchArea(0) {
    }

    bool eventFilter(QObject *, QEvent *event) {
        if (event->type() == QEvent::TouchUpdate) {
            qDebug() << "processing TouchUpdate...";
        }
        // other Touch events here...

        return false;
    }

    QQuickItem *targetTouchArea() const {
        return mTargetTouchArea;
    }

    void setTargetTouchArea(QQuickItem *targetTouchArea) {
        if (targetTouchArea == mTargetTouchArea)
            return;

        if (mTargetTouchArea)
            mTargetTouchArea->removeEventFilter(this);

        mTargetTouchArea = targetTouchArea;

        if (mTargetTouchArea)
            mTargetTouchArea->installEventFilter(this);

        emit targetTouchAreaChanged();
    }

signals:
    void targetTouchAreaChanged();

private:
    QQuickItem *mTargetTouchArea;
};

int main(int argc, char *argv[])
{
    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<CustomTouchArea>("App", 1, 0, "CustomTouchArea");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

#include "main.moc"

main.qml:

import QtQuick 2.3
import QtQuick.Window 2.2

import App 1.0

Window {
    visible: true
    width: 300
    height: 300

    Rectangle {
        id: rectangle1
        anchors.centerIn: parent
        width: 150
        height: width
        color: "red"
        MultiPointTouchArea {
            id: touchArea
            anchors.fill: parent
            mouseEnabled: false
            onTouchUpdated: {
                console.log("Bottom touch area contains:",
                            touchPoints.length,
                            "touches.")
            }
        }
    }
    Rectangle {
        id: rectangle2
        anchors.centerIn: parent
        width: 100
        height: width
        color: "blue"
        CustomTouchArea {
            targetTouchArea: touchArea
            anchors.fill: parent
        }
    }
}

You can read more about event filters here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!