检测接触点之外的手势

时间:2019-01-09 13:09:50

标签: qt

我具有根据触摸事件类型检测手势的方法:

void Viewport::touchEvent(QTouchEvent *event)
{
    switch (event->type()) {
    case QEvent::TouchBegin:
        qDebug() << __func__ << "Touch beings: " << event->type();
        break;
    case QEvent::TouchEnd:
        qDebug() << __func__ << "Touch ends: " << event->type();
        break;
    case QEvent::TouchUpdate:
        qDebug() << __func__ << "Touch updates: "<< event->type();
        break;
    case QEvent::TouchCancel:
        qDebug() << __func__ << "Touch cancels: " << event->type();
        break;
    default:
        break;
    }    
}

我正在寻找一种Qt工具,用于检测触摸手势,例如,捏和捏。我对this page的理解是QGestureEventQGesture只能与窗口小部件一起使用。我想知道Qt是否有任何手势识别工具,即使没有小部件也可以在任何地方使用。

1 个答案:

答案 0 :(得分:0)

最后,我开发了一种自制程序算法来检测类似这样的捏手势:

void Viewport::touchEvent(QTouchEvent *event)
{
    switch (event->type()) {
    case QEvent::TouchUpdate: // Only consider "update" case, does it make sense?
        if(/* Everything is OK */) {
            detectGesturePinch(event); // Method containing the detection algorithm
            event->accept();
        }
        else
            event->ignore();
        break;
    default:
        break;
    }

}

实际的捏手势检测算法:

void Viewport::detectGesturePinch(QTouchEvent *event)
{
    // We are concerned with two fingers on touch screen, not more, not less
    if (event->touchPoints().length() == 2) {
        QTouchEvent::TouchPoint point1 = event->touchPoints().at(0);
        QTouchEvent::TouchPoint point2 = event->touchPoints().at(1);

        qDebug() << __func__ << "Point 1 state: " << point1.state();
        qDebug() << __func__ << "Point 2 state: " << point2.state();
        qDebug() << __func__ << "Point 1: " << point1;
        qDebug() << __func__ << "Point 2: " << point2;

        // Both fingers should be moving, right?
        if (point1.state() == Qt::TouchPointMoved &&
                point2.state() == Qt::TouchPointMoved) {

            qDebug() << __func__ << " Both points moving";

            QVector2D vec1 = QVector2D(point1.pos() - point1.lastPos());
            QVector2D vec2 = QVector2D(point2.pos() - point2.lastPos());
            vec1.normalize();
            vec2.normalize();

            // The relative angle of two fingers moving
            // Dot product gives a measure of relative angle
            qreal angleFactor = QVector2D::dotProduct( vec1, vec2);

            // To see if two fingers are moving apart or moving toward eachother
            QVector2D delta = QVector2D(point1.pos() - point2.pos());
            QVector2D lastDelta = QVector2D(point1.lastPos() - point2.lastPos());

            if ( angleFactor < m_gesturePinchAngleThreshold && delta.length() > lastDelta.length() ) {
                qDebug() << __func__ << "Angle factor: " << angleFactor << "Gesture is pinch-out!";
            }
            if ( angleFactor < m_gesturePinchAngleThreshold && delta.length() < lastDelta.length() ) {
                qDebug() << __func__ << "Angle factor: " << angleFactor << "Gesture is pinch-in!";
            }
        }
    }
}

例如,m_gesturePinchAngleThreshold类型的double可以初始化为0.8,以控制两个捏手指的相对角度。