2016-02-10 3 views
1

Я хочу создать объект, который будет работать как MultiPointTouchArea (так что он будет иметь осязаемый сигнал), но также он не будет красть касания, так что объекты, расположенные под ним, получат прикосновение событий.Объект для обработки события касания, но также разрешите его через

Для решения может потребоваться создание объекта 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.") 
      } 
     } 
    } 
} 

Если я найду решение работать я отправлю его здесь. Сейчас я буду пытаться реализовать Mitchsolution.

+0

Вы пытались установить значение «MultiPointTouchArea.mouseEnabled» на false? – mkrus

+0

@mkrus Я пробовал. Это не работает. –

ответ

2

Вы можете создать подкласс QQuickItem и переопределить функцию touchEvent():

Этот обработчик событий может быть переопределен в подклассе, чтобы получать события касания для элемента. Информация о событии предоставляется параметром события.

Вы, вероятно, нужно явно задать accepted для false, чтобы гарантировать, что элемент не красть события:

Установка параметра принимает указывает на то, что приемник событий хочет событие. Нежелательные события могут быть переданы родительскому виджету. По умолчанию isAccepted() имеет значение true, но не полагается на это, поскольку подклассы могут выбрать очистить его в своем конструкторе.


я могу проверить, что выше приведет к нижней части сенсорного принимая все события после того, как пресса (протестировано на Android телефон). В этом случае вам нужно каким-то образом отфильтровать события. Один из способов сделать это - внутри вашего подкласса QQuickItem объявить свойство, которое будет использоваться для указания на нижнюю зону касания. При том, что изменения свойств, установите фильтр событий на сенсорной области:

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.

+1

У меня проблема с этим. Я могу переопределить функцию 'touchEvent()', но если я вызову 'setAccepted (false)', я прекращу принимать события, а затем они будут отправлены на объекты ниже. Кажется, что тот же 'QEvent' может использоваться только одним объектом за раз. –

+0

Правда, я не проверял это. Ответ был обновлен. – Mitch