What's New in Qt 5.1: The QtSensors Module

By Jeff Tranter

Introduction

The QtSensors module is a new feature in Qt 5.1. It provides access to sensor hardware from QML and C++. Sensors are common on embedded devices such as smart phones and include hardware like an accelerometer, compass and tilt sensor. The QtSensors API also provides a motion gesture recognition API.

Back ends are provided for Blackberry 10, Android, Linux, iOS, Sensorfw (an open source sensor framework and daemon originally developed for MeeGo) and some generic back ends that provide emulation of sensors that are not supported on the platform. Currently the best supported platform is BlackBerry 10 followed by Sensorfw.

The API is mostly source compatible with the sensors that were provided by Qt Mobility 1.2 which was an add-on for Qt 4 for mobile devices. The documentation includes a porting guide outlining the differences between Qt Mobility and QtSensors.

QML Interface

The QML interface provides over a dozen QML components for the different types of supported sensors, most of which are derived from the Sensor base type.

The sensor component types are: Accelerometer, Altimeter, AmbientLightSensor, AmbientTemperatureSensor, Compass, Gyroscope, HolsterSensor, IRProximitySensor, LightSensor, Magnetometer, OrientationSensor, PressureSensor, ProximitySensor, RotationSensor, TapSensor and TiltSensor.

It also provides a set of components such as AccelerometerReading to hold sensor readings from a particular type of sensor.

To use the sensors components from QML use the following import statement:

    import QtSensors 5.0

You can then use the components, such as Compass, from QML.

C++ Interface

For C++ development the sensors are exposed as C++ classes, both for the devices and for storing readings from the devices. Over 50 classes are provided such as QAccelerometer and QAccelerometerReading.

To use the sensors module add it in your qmake project file, e.g.

    QT += sensors

As usual, the Qt documentation describes all of the classes and APIs in detail.

Examples

Here is a very simple QML example that reads and outputs accelerometer data every second to the console:

import QtSensors 5.0

Accelerometer {
    dataRate: 1
    active:true

    onReadingChanged: {
        print("Acceleration: x =", reading.x, "y =", reading.y, "z =", reading.z);
    }
}

On my desktop system where the back end is simulated I get readings like this which correspond to a device oriented vertically on the Y axis:

Acceleration: x = 0 y = 9.8 z = 0
Acceleration: x = 0 y = 9.8 z = 0
Acceleration: x = 0 y = 9.8 z = 0
Acceleration: x = 0 y = 9.8 z = 0
…

I also wrote a small C++ example application that displays similar information to the QML example above. Here is a screen shot of the application running:

Here is the header file for the implementation's subclass of QMainWindow. It keeps private instance variables for a QAccelerometer object and a QAccelerometerReading. A slot is defined that will update the text edit with the readings.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QAccelerometer>
#include <QAccelerometerReading>
#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void update();

private:
    Ui::MainWindow *ui;
    QAccelerometer *accel;
    QAccelerometerReading *reading;
};

#endif // MAINWINDOW_H

The implementation of the class creates a QAccelerometer instance in the constructor, connects the sensors readingChanged() signal to the slot, sets the data rate to once per second, and starts the sensor. In the slot it gets the reading by calling the sensor's reading()method then gets and displays the x, y, and z acceleration values in the text edit.

#include <QDateTime>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    accel = new QAccelerometer;
    connect(accel, SIGNAL(readingChanged()), this, SLOT(update()));
    accel->setDataRate(1);
    accel->start();
}

MainWindow::~MainWindow()
{
    delete accel;
    delete ui;
}

void MainWindow::update()
{
    QString text;

    reading = accel->reading();
    text = tr("%1\nAcceleration:\n  x = %2\n  y = %3\n  z = %4").arg(QDateTime::currentDateTime().toString()).arg(reading->x()).arg(reading->y()).arg(reading->z());
    ui->textEdit->setText(text);
}

The QtSensors code includes a number of QML and C++ programming examples. Here is a screenshot of one of them, the Sensor Explorer, which is a QML example application that demonstrates how to read the metadata of available sensors.

The documentation also includes an example of how to write a new sensor back end (the Grue Sensor Example).

Summary

Currently QtSensors is mostly applicable to mobile and embedded systems. There has been some discussion recently about adding support for sensors on desktop hardware like CPU (e.g. temperature), GPU, and hard disk drives, so that may possibly happen in the future.

In conclusion, the new QtSensors module in Qt 5.1 allows reading sensor data in a portable way from C++ or QML, something that is critical for many embedded or mobile applications.

The full source code for the C++ example can be downloaded from here.

Note that the above information was based on the Qt 5.1 RC release and could possibly change before Qt 5.1.0 final.