Qt-based BB10 API Examples Documentation

Contents

Compass Example

Files:

Description

The Compass example demonstrates how to use sensors from the QtSensors module to implement a compass UI.

Overview

In this example we'll learn how to use the QCompass, QCompassFilter and QCompassReading classes to implement a simple compass UI in Cascades.

The UI

The UI of this sample application consists of an ImageView that shows the compass rose and a Label that shows the current angle in degree.

The business logic of the application is encapsulated in the CompassSensor class which is made available to the UI under the name '_compass'.

    CompassView {
        rotationZ: -_compass.azimuth

        // Disable implicit animations to avoid ugly "jumps" when switching from 0 degrees to 360 degrees and vice versa
        attachedObjects: ImplicitAnimationController {
            propertyName: "rotationZ"
            enabled: false
        }
    }

The compass rose image is rotated according to the azimuth angle as reported by the sensor object. To avoid the implicit animation on the 0 <-> 360 degree switch, we disable the implicit animation for the 'rotationZ' property explicitly.

    Label {
        text: Math.round(_compass.azimuth) + "°"
        textStyle {
            base: SystemDefaults.TextStyles.BigText
            color: Color.White
            fontWeight: FontWeight.Bold
        }
    }

The Label shows the current azimuth angle as reported by the sensor object.

CompassSensor

The CompassSensor encapsulates the business logic of the application. It contains a QCompass object, which does the low-level communication with the compass sensor of the device, and provides a property 'azimuth' to make the retrieved sensor data available to the UI. It inherits from QCompassFilter and reimplements the 'bool filter(QCompassReading*)' method to retrieve the sensor data from the QCompass object.

    class CompassSensor : public QObject, public QCompassFilter
    {
        Q_OBJECT

        // The property to access the azimuth value of the compass sensor
        Q_PROPERTY(qreal azimuth READ azimuth NOTIFY azimuthChanged)

    public:
        CompassSensor(QObject *parent = 0);

        // The accessor method for the azimuth property
        qreal azimuth() const;

    Q_SIGNALS:
        // The change notification signal of the azimuth property
        void azimuthChanged();

    protected:
        /**
         * This method is reimplemented from the QCompassFilter interface and is
         * called by the QCompass whenever new values are available.
         */
        bool filter(QCompassReading *reading);

    private:
        // The compass sensor
        QCompass m_compassSensor;

        // The azimuth value
        qreal m_azimuth;
    };

Inside the constructor we try to connect the QCompass object to the hardware backend. If that's successful, we register the CompassSensor class as filter for the QCompass object and start the sensor to gather data.

    CompassSensor::CompassSensor(QObject *parent)
        : QObject(parent)
        , m_azimuth(0)
    {
        // We'd like to lock to the initial orientation
        OrientationSupport::instance()->setSupportedDisplayOrientation(SupportedDisplayOrientation::CurrentLocked);

        // At first we have to connect to the sensor backend...
        if (!m_compassSensor.connectToBackend()) {
            qWarning() << "Cannot connect to compass sensor backend!";
        }

        // ... and then add a filter that will process the read data
        m_compassSensor.addFilter(this);

        // Do not report duplicated values
        m_compassSensor.setSkipDuplicates(true);

        // Start gathering the data
        m_compassSensor.start();
    }

The 'bool filter(QCompassReading*)' method is called whenever the QCompass object retrieved new data from the hardware sensor. Inside this method we update our internal azimuth property with the new value from the sensor and emit the change notification signal if the new value differs from the previous one.

    bool CompassSensor::filter(QCompassReading *reading)
    {
        // Store the previous azimuth
        const qreal oldAzimuth = m_azimuth;

        m_azimuth = reading->azimuth();

        // Emit changed signal if azimuth has changed
        if (oldAzimuth != m_azimuth)
            emit azimuthChanged();

        // Do no further processing of the sensor data
        return false;
    }