Calendar

« February 2011 »
Mo Tu We Th Fr Sa Su
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28            

Raw multitouch pointer events in QML

LateJ | 03 February, 2011 08:45

While implementing one QML application, I needed to have access to multitouch pointer events. QML has a MouseArea element for handling pointer input, but unfortunately it does not support multitouch events. So by default you are limited to single touch pointer events. GestureArea (from Qt.labs) can be used to handle multitouch gestures, but I needed just the raw coordinates of the current touch points.

Before going any further, I want to point out that there's also a new element called TouchArea that is coming to QML. It seems to provide pretty much the same functionality that I'm implementing here, so in the future this post will probably become quite irrelevant.

The Qt Quick application created by the application wizard in Qt Creator contains a QmlApplicationViewer class, which handles things like orientation lock etc. The QmlApplicationViewer is actually inherited from QDeclarativeView, so it's easy to extend its functionality. One could also modify the QmlApplicationViewer class itself, but this is not a good idea since new Qt Creator versions will probably have updated version of the class, and modifying it would make updating difficult.

To intercept multitouch events and deliver them to QML, I did the following:

  • Inherit a new class (TouchApplicationViewer) from QmlApplicationViewer and reimplement viewportEvent(QEvent*) method
  • Implement a class MultiTouch which exposes a list of touch points to QML.
TouchApplicationViewer implementation is quite simple, for touch events it updates the touch point list and in case of other events it just forwards them to the base class.

touchapplicationviewer.h touchapplicationviewer.cpp
#ifndef TOUCHAPPLICATIONVIEWER_H
#define TOUCHAPPLICATIONVIEWER_H

#include "qmlapplicationviewer.h"

class MultiTouch;

class TouchApplicationViewer : public QmlApplicationViewer
{
    Q_OBJECT

public:
    explicit TouchApplicationViewer(MultiTouch* touch, QWidget *parent = 0);
    bool viewportEvent(QEvent *event);

signals:

public slots:

private:
    MultiTouch* m_touch;
};

#endif // TOUCHAPPLICATIONVIEWER_H
#include "touchapplicationviewer.h"
#include "multitouch.h"

#include <QMouseEvent>

TouchApplicationViewer::TouchApplicationViewer(MultiTouch* touch, QWidget *parent) :
    QmlApplicationViewer(parent), m_touch(touch)
{
    qmlRegisterType<TouchPoint>("Multitouch", 1, 0, "TouchPoint");
}

bool TouchApplicationViewer::viewportEvent(QEvent *event)
{
    if (!m_touch)
    {
        return QmlApplicationViewer::viewportEvent(event);
    }

    switch (event->type())
    {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
        m_touch->update(*(static_cast<QTouchEvent *>(event)));
        return true;
    default:
        return QmlApplicationViewer::viewportEvent(event);
    }
} 

For exposing the touch point list to QML, I implemented two classes, TouchPoint and MultiTouch. MultiTouch class exposes the list of touchpoints to QML as a QList<TouchPoint*>. The sources for these classes are included in the attached project.

The test application is very simple. It shows the number of touch points in the middle of the screen, and also draws colored circles in the touch point coordinates. Here's a screenshot of the application running on device with two fingers on the screen:

Screenshot demonstrating the example application

And here's the QML source code for the application:

import QtQuick 1.0
import Multitouch 1.0

Rectangle {
    id: root
    width: 360
    height: 640

    property variant touchPoints: multitouch.touchPoints

    Repeater {
        id: repeater
        anchors.fill: parent
        model: touchPoints.length

        Rectangle {
            color: index == 0 ? "blue" : "red"
            x: touchPoints[index].x - width/2
            y: touchPoints[index].y - height/2
            width: 80
            height: 80
            radius: 40
        }
    }

    Text {
        id: textfield
        text: "Touch points: "+touchPoints.length
        anchors.centerIn: parent
    }
}

Download the example here.


RSSComments

Very helpful

adrz1 | 19/04/2012, 19:45

Thanks, i have implemented a two button control for a simple QML game using your idea.

You must login to post comments. Login
 
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved