处理触摸事件但也让它通过的对象 [英] Object to process touch event but also let it through

查看:15
本文介绍了处理触摸事件但也让它通过的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create an object that will work like MultiPointTouchArea (so it will have touchUpdated signal) but also it would not steal touches, so that objects placed beneath it will receive the touch events as well.

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

The solution may require creating C++ object.

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

Is there a simple way to create such object? Is it possible to process (touch) events without "stealing" them? Any hint will be appreciated.

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

Here is an example of what I am trying to do. I want to touch top Rectangle but at the same time I want both MultiPointTouchAreas process touches:

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.")
            }
        }
    }
}

如果我能找到可行的解决方案,我会在此处发布.我现在将尝试实现 Mitch解决方案.

If I will find working solution I will post it here. I will be trying now to implement Mitch's solution.

推荐答案

你可以继承 QQuickItem 并覆盖 touchEvent() 函数:

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

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

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.

您可能需要明确设置 acceptedfalse 以确保该项目不会窃取事件:

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

设置accept参数表示事件接收者想要该事件.不需要的事件可能会传播到父小部件.默认情况下,isAccepted() 设置为 true,但不要依赖它,因为子类可能会选择在其构造函数中清除它.

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.

<小时>

我可以验证上述操作会导致下触摸区域在按下后处理所有事件(在 Android 手机上测试).在这种情况下,您需要以某种方式过滤事件.一种方法是,在您的 QQuickItem 子类中,声明一个将用于指向下部触摸区域的属性.当该属性发生变化时,在触摸区域安装一个事件过滤器:


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:

ma​​in.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"

ma​​in.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.

这篇关于处理触摸事件但也让它通过的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆