Sunday, September 26, 2010

Detecting Tap And Hold (Long Press) event in Qt

Recently while working on Qt project I required to recognize Tap and Hold (Long Press) gesture. Qt introduced new gesture handler library in 4.6 but some how it was not working on my machine and I needed to create my own solution. I already have created one custom solution for detecting Tap and Hold for iOS and I tried to port same thing to Qt as well.

Following is my code to detect Tap and Hold for Qt. In code I am starting timer on mouse press event, if timer expire then we have Tap and Hold event. If user release mouse while timer is still active then Tap and Hold is canceled.
#ifndef MYTAPANDHOLDGESTURE_H
#define MYTAPANDHOLDGESTURE_H

#include <QObject>

class QTimer;

class MyTapAndHoldGesture: public QObject
{
    Q_OBJECT
public:
    MyTapAndHoldGesture( QObject *parent = 0 );
    void handleEvent( QEvent *event);

signals:
    void handleTapAndHold();

private slots:
    void timeout();

private:
    QTimer* _timer;
};

#endif // MYTAPANDHOLDGESTURE_H

#include "mytapandholdgesture.h"

#include <QMouseEvent>
#include <QTimer>

MyTapAndHoldGesture::MyTapAndHoldGesture( QObject *parent )
{
    _timer = new QTimer(this);
    connect(_timer,SIGNAL(timeout()),this,SLOT(timeout()));
}

void MyTapAndHoldGesture::handleEvent( QEvent *event)
{
    if( event->type() == QEvent::MouseButtonPress ) {
        _timer->start( 1000 );
    } else if( event->type() == QEvent::MouseButtonRelease ) {
        if( _timer->isActive() ) {
            // tap and hold canceled
            _timer->stop();
        }
    } else if( event->type() == QEvent::MouseMove ) {
        // tap and hold canceled
        _timer->stop();
    }
}

void MyTapAndHoldGesture::timeout()
{
    emit handleTapAndHold();
    _timer->stop();
}

Widget code for testing.
#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include <QWidget>

class MyTapAndHoldGesture;

class TestWidget : public QWidget
{
    Q_OBJECT
public:
    TestWidget(QWidget *parent = 0);

private:
    bool event(QEvent *event);

private slots:
    void tapAndHold();

private:
    MyTapAndHoldGesture* _gestureHandler;
};

#endif // TESTWIDGET_H

#include "testwidget.h"
#include <QDebug>
#include "mytapandholdgesture.h"

TestWidget::TestWidget(QWidget *parent) :
    QWidget(parent)
{
    _gestureHandler = new MyTapAndHoldGesture(this);
    connect(_gestureHandler,SIGNAL(handleTapAndHold()),
    this,SLOT(tapAndHold()));
}

bool TestWidget::event(QEvent *event)
{
    _gestureHandler->handleEvent( event );
    return QWidget::event(event);
}

void TestWidget::tapAndHold()
{
    qDebug() << "tapAndHold";
}

No comments:

Post a Comment