using multi-touch and gestures with qt
DESCRIPTION
With the introduction of multi-touch and gesture support coming in Qt, application developers now have the possibility of introducing new types of input and interaction to their applications. We will examine the various types of devices that one can expect to encounter in the multi-touch and gesture "world". This presentation will also introduce and explain the new API, walk through some example code, and show some demos of some of the possibilities we foresee with this technology. Presentation by Jens Bache-Wiig held during Qt Developer Days 2009. http://qt.nokia.com/developer/learning/elearningTRANSCRIPT
Using Multi-Touch and Gestures with Qt Jens Bache-Wiig 10/09/09
Introduction
Jens Bache-Wiig • Worked on Qt since 2005
• Platform Team
• Interim Widget Pimp
2
Agenda
• Introduction
Concepts
API
Examples
Q&A
3
Agenda
Introduction
• Concepts
API
Examples
Q&A
4
Concepts
What do we mean when we say multi-touch?
5
Concepts
A widget reacts to multiple touch-points
For example, to zoom/scale content...
6
Lorem ipsum dolor sit eamt. Dolore magna aliquam erat volupat...cvc
Lorem ipsum dolor sit eamt. Dolore magna aliquam erat volupat. Ut enim ad minimum veniami quis. Duis sutem vel eum irure dolor in rerit laputum
Concepts
Multiple widgets react to multiple touch-points For example, moving several sliders at once...
7
Concepts
Real life is multi-touch Do you open a bottle with one finger? Applications could do it too...
8
1
2
Concepts
Part of our future since at least 1982...
9
Disney © 1982
Concepts
Sony Pictures © 2009
10
hBp://www.youtube.com
Concepts
What do we mean when we say gestures?
12
Concepts
A way to make common multi-touch use-cases easy to use in your application
• Standard, platform-specific touch-based gestures • Extensible API for custom gestures
13
Concepts
What are standard gestures?
• Built-in multi-touch gestures that work in standard Qt widgets
14
Concepts
Pan gesture
• Scrolls content • Works in all scrollable Qt widgets
15
Lorem ipsum dolor sit eamt. Dolore magna aliquam erat volupat. Ut enim ad minimum veniami quis. Duis sutem vel eum irure dolor in rerit laputum
Ut enim ad minimum veniami quis. Duis sutem vel eum irure dolor in rerit laputum
Concepts
Pinch gesture
Zoom and/or rotate content
16
Agenda
Introduction
Concepts
• API
Examples
Q&A
17
API
Multi-touch • New event types
• TouchBegin • TouchUpdate • TouchEnd
• New QTouchEvent class • QWidget and QGraphicsItem API
18
API
QEvent::TouchBegin • First in sequence • Must be accepted to receive following events
19
API
QEvent::TouchUpdate • Normal event indicating activity • Expect more events to follow
20
API
QEvent::TouchEnd • Final event in sequence • No more events without a new TouchBegin
21
API
TouchBegin propagation • When ignored, propagate to widget under first touch-
point • Widgets never receive multiple TouchBegin • New touch-points on children are combined with first
touch-point
22
1 21
One event, one point, to grey widget One event, two points, to grey widget
API
TouchUpdate, TouchEnd do not propagate
23
API
QTouchEvent • Event class for QWidget and QGraphicsItem • Contains list of active touch points • Device type – TouchScreen or TouchPad
24
API
QTouchEvent::TouchPoint • Information about one touch-point • Integer identifier • Primary touch-point flag • State - Pressed, Moved, Stationary, or Released • Current, previous, starting positions • Local, scene, screen, normalized translations • Area, pressure (if supported by device)
25
API
Touch events are not sent by default • Must be enabled first • When enabled, TouchBegin event will be accepted
unless explicitly ignored
26
API
Qt::WA_AcceptsTouchEvents • Set on QWidget to receive touch events • To handle events, reimplement QWidget::event() • Default implementation emulates mouse events for first
non-primary touch-point • Set on viewport() of QAbstractScrollArea based
widgets • To handle events, reimplement
QAbstractScrollArea::viewportEvent()
27
API
QGraphicsItem::setAcceptsTouchEvents(bool) • Set to true on item to receive touch events • To handle, reimplement QGraphicsItem::sceneEvent() • No default implementation
28
API
Gestures
• QGesture and QGestureRecognizer classes • Widgets subscribe to gestures • Using standard gestures • Implementing custom gestures
29
API
QGesture • Base class for more complex gestures • Basic properties and convenience functions • Delivered to QWidget or QGraphicsObject • State (Started, Updated, Finished, Canceled)
QGestureEvent • Contains a list of QGestures • Normal event propagation rules apply
30
API
QGestureRecognizer • “Just” an event filter + state machine • Registered in QApplication • Announces when a gesture is triggered
31
API
How do I use a gesture? • Use grabGesture() to request it • Handle the QGestureEvent and get:
QPanGesture - Offset property
QPinchGesture - Center-point, rotation, scale properties
32
API
Implementing custom gestures • Create a state machine:
- subclass QGestureRecognizer - implement filterEvent(), createGesture(), reset()
• Create a gesture object: - subclass QGesture (optional) - fill QGesture with properties
33
API
Gestures can be simple : Four finger tap class FourFingerTapGesture : public QGestureRecognizer { virtual Result filterEvent(QGesture *, QObject *, QEvent *event) { if (event->type() == QEvent::TouchUpdate) if (static_cast<QTouchEvent *>(event)->touchPoints.size() == 4) return GestureFinished;
return Ignore; } };
34
API
Gestures can be complex • Event filter could implement a state machine • Continuous gesture going through Qt::GestureStated
to Qt::GestureUpdated to Qt::GestureFinished states.
• Gesture may need to hijack events, store them, and replay them later
35
API
Special considerations when implementing and/or using gestures
36
API
Single gesture on parent widget with children • Should the parent's gesture filter events for children?
GestureContext • widget-only gesture • widget-with-children gesture
37
API
Multiple gestures on a single widget • All gestures filter incoming events in undefined order • Ignored gestures will be propagated • You can partially ignore a gesture:
bool gestureEvent(QGestureEvent *event) { event->ignore(Qt::PanGesture); event->accept(Qt::PinchGesture); return true; }
38
API
Gesture has priority over normal event handling
• Gesture may need several events before starting
• Normal event handling interferes with gesture
• Events should be delayed
39
Agenda
Introduction
Concepts
API
• Examples
Q&A
40
API
ITAI: PictureBlue by Ariel Molina
41
h$p://vimeo.com/4990545
Examples
Using QTouchEvent...
MyWidget::MyWidget(QWidget *parent) { setAttribute(Qt::WA_AcceptsTouchEvents); }
42
Examples
Using QTouchEvent...
bool MyWidget::event(QEvent *e) { switch (e->type()) { case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: { // creative stuff here } }
43
Examples
Using QTouchEvent...
QTouchEvent *te = static_cast<QTouchEvent *>(e); QList<QTouchEvent::TouchPoint> points = te->touchPoints();
if (touchPoints.count() == 2) { // Do something interesting here }
44
Examples
Using QTouchEvent...
// determine scale factor QTouchEvent::TouchPoint p0 = touchPoints.first(); QTouchEvent::TouchPoint p1 = touchPoints.last(); QLineF line1(p0.startPos(), p1.startPos()); QLineF line2(p0.pos(), p1.pos()); qreal scaleFactor = line2.length() / line1.length(); setContentScale(scaleFactor);
45
Examples
Using QTouchEvent...
// determine angle between previous and current pos QTouchEvent::TouchPoint p0 = touchPoints.first(); QTouchEvent::TouchPoint p1 = touchPoints.last(); QLineF line1(p0.lastPos(), p1.lastPos()); QLineF line2(p0.pos(), p1.pos()); qreal angle = line2.angleTo(line1); rotateContentBy(angle);
46
And now some gestures...
Examples
Custom gesture – four finger tap class FourFingerTapGesture : public QGestureRecognizer { virtual QGesture createGesture(QObject *) {
return new QGesture(“FourFingerTap”); }
}
virtual Result filterEvent(QGesture *state, QObject *, QEvent *event) {
if (event->type() == QEvent::TouchUpdate)
if (static_cast<QTouchEvent *>(event)->touchPoints.size() == 4) {
state->setProperty(“foo”, QLatin1String(“bar”));
return GestureFinished;
}
return Ignore;
}
}; 48
Examples
Custom gesture – four finger tap class Label : public QLabel { virtual void gestureEvent(QGestureEvent *event) { if (QGesture *g = event->gesture(“FourFingerTap”)) { setText(g->property(“foo”));
event->accept(g);
} ...
QLabel *label = new Qlabel;
label->setPixmap(QPixmap(“qt-logo.png”));
label->grabGesture(“FourFingerTap”);
49
Agenda
Introduction
Concepts
API
Examples
• Q&A
50
Thanks!
Any Questions?
51