对象处理触摸事件,但也让它通过



我想创建一个像MultiPointTouchArea一样工作的对象(所以它会有touchUpdate信号(,但它也不会窃取触摸,这样放置在它下面的对象也会接收触摸事件。

解决方案可能需要创建C++对象。

有没有一种简单的方法来创建这样的对象?是否可以在不"窃取"事件的情况下处理(触摸(事件?任何提示将不胜感激。


这是我正在尝试做的事情的一个例子。我想触摸顶部Rectangle但同时我想要两个MultiPointTouchArea过程触摸:

import QtQuick 2.3
import QtQuick.Window 2.2
Window {
    visible: true
    width: 300
    height: 300
    Rectangle {
        id: rectangle1
        anchors.centerIn: parent
        width: 150
        height: width
        color: "red"
        MultiPointTouchArea {
            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"
        MultiPointTouchArea {
            anchors.fill: parent
            mouseEnabled: false
            onTouchUpdated: {
                console.log("Top touch area contains:",
                            touchPoints.length,
                            "touches.")
            }
        }
    }
}

如果我能找到可行的解决方案,我会在这里发布。我现在将尝试实施米奇的解决方案。

您可以子类QQuickItem并覆盖touchEvent()函数:

可以在子类中重新实现此事件处理程序,以接收项的触摸事件。事件信息由事件参数提供。

您可能需要将accepted显式设置为 false,以确保该项目不会窃取事件:

设置 accept 参数指示事件接收器需要该事件。不需要的事件可能会传播到父小组件。默认情况下,isAccept(( 设置为 true,但不要依赖它,因为子类可以选择在其构造函数中清除它。


我可以验证上述内容是否会导致较低的触摸区域在按下后采取所有事件(在Android手机上测试(。在这种情况下,您需要以某种方式过滤事件。一种方法是在 QQuickItem 子类中声明一个属性,该属性将用于指向较低的触摸区域。当该属性更改时,在触摸区域安装事件筛选器:

主.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
        }
    }
}

您可以在此处阅读有关事件过滤器的更多信息。

最新更新