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

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

问题描述

我想创建一个像 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:


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

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.

您可能需要显式设置 接受 false 以确保该项目不会窃取事件:

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.



< hr>

我可以验证以上内容将导致按下后所有事件的较低触摸区域(在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:

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

您可以阅读有关事件过滤器的更多信息 here

You can read more about event filters here.

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

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