Tacti Phone

Working with GPS in Qt

Working with GPS in Qt

In this article, I will describe how to write a simple program that will display the coordinates of your movement. The development process will consist of three steps: connecting the necessary libraries, developing logic, visualizing the result.

1. Connecting the required libraries

To work with the phone’s GPS sensor, Qt uses the QGeoPositionInfoSource class from the Qt Mobility package.
To connect it to the project, you need to tell qmake that we want to use Qt Mobility, namely the Location module.
To do this, open the following lines in the profile of your project: Now we include the header file describing the QGeoPositionInfoSource class and call the QTM_USE_NAMESPACE macro,
CONFIG += mobility
MOBILITY += location

1.#include <QGeoPositionInfoSource>

Attention! In Qt5 grade class QGeoPositionInfoSource transferred to the module QtLocation.
In addition, if you are writing an application for Symbian, you must declare the appropriate permissions for using GPS (Capabilities) in the profile:
symbian:TARGET.CAPABILITY += Location
Now you can proceed to write the application logic.

2. Get GPS coordinates from Qt

Coordinates are obtained in 4 stages.
1. Creation of a new instance of the QGeoPositionInfoSource class. To do this, the createDefaultSource method is used, which returns a source that reads coordinates from the default geodata source. In principle, it may not even be GPS coordinates, but A-GPS, or even GLONASS.
2. Connection of the necessary signals and slots ( position updates and update timeout );
3. Setting the interval and making requests to obtain device coordinates using the set update interval and start updates methods ;
4. Processing the obtained coordinates by transferring them to the QML interface.
Below is the code that implements all of this.

01.gpsTest::gpsTest(QObject *parent) :
04.// 1. 
05.QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
06.// 2. 
07.connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(slotPositionUpdated(QGeoPositionInfo)));
08.connect(source, SIGNAL(updateTimeout()), this, SLOT(slotPositionTimeout()));
09.// 3. 
10.// Если задать 0, то частота запросов будет автоматически регулироваться классом
15.void gpsTest::slotPositionUpdated(QGeoPositionInfo info)
17.QGeoCoordinate coordinate = info.coordinate();
18.emit gotCoordinates(QVariant(coordinate.latitude()), QVariant(coordinate.longitude()));
21.void gpsTest::slotPositionTimeout()
23.qDebug() << "timeout";

3. Visualization of phone movement

After receiving the coordinates, the gotCoordinates signal is generated. The slot associated with this signal is in the QML code.
There are many examples on the internet of how to connect a Qt signal to a QML slot. To do this, you need to get a pointer to the QGraphicsObject associated with the QmlApplicationViewer. After that, signals and slots are connected according to the standard scheme using connect ():

01.Q_DECL_EXPORT int main(int argc, char *argv[])
03.QScopedPointer<QApplication> app(createApplication(argc, argv));
04.QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
08.gpsTest *test = new gpsTest(app);
09.QObject *graphics = dynamic_cast<QGraphicsObject*> ((QGraphicsObject*)viewer.data()->rootObject());
10.QObject::connect(test, SIGNAL(gotCoordinates(QVariant,QVariant)), graphics, SLOT(gotCoordinates(QVariant,QVariant)));
11.return app->exec();

Slots in QML are declared as simple functions, so it is enough to simply declare the function of the same name:

1.function gotCoordinates(lattitude, longitude)
3.console.log("x: " + lattitude +
4."y: " + longitude);

To visualize the movement of the phone, I will simply display a list of the coordinates that the phone was at. To do this, you need to declare a Flickable area in QML, and is it a Text element with a list of coordinates. The Flickable object is needed so that you can flip through multi-line text. Without it, only the upper lines of text will be displayed on the screen, and the lower ones will go beyond the screen area and will be inaccessible.

02.id: flickable
03.anchors.fill: parent
05.contentHeight: data.paintedHeight
06.contentWidth: data.paintedWidth
08.id: data
09.width: flickable.width
10.height: flickable.height

The coordinate list will now scroll normally across the screen.