Qt SDK best practices

As you continue developing apps, you should know a few details that can make your apps perform better and encounter fewer problems. This topic discusses important details that you should keep in mind.

Map view options

The ArcGIS Runtime SDK for Qt offers three patterns for displaying a map in a map view. The one you choose will depend on your resources, platform, experience, and need for speed. Choose the map view type for your app using the table below.

Map view types

App PatternUse this API Use this map view typeRuns on Windows, Linux or macOSRuns on iOS and Android

QML (Qt Quick)

QML

MapView

Yes

Yes

C++ (Qt Widgets)

C++

MapGraphicsView

Yes

No

C++ with QML UI (Qt Quick)

C++

MapQuickView

Yes

Yes

Write your app in QML

If you are familiar with the QML API from The Qt Company, you already know how quickly you can produce a powerful app with QML. QML offers a declarative, highly-readable syntax for designing and building responsive and fluid user interfaces for native desktop and mobile applications. ArcGIS Runtime SDK for Qt extends QML with QML types that provide ArcGIS Runtime functionality. Objects are declared hierarchically and have bindable properties to provide automatically dynamic behavior. JavaScript functions are used to provide procedural code when needed. This is a powerful feature for developers who are familiar with Web development who want to develop native apps. QML has been part of the SDK since version 10.2.5, and works on all supported platforms.

Declare a Rectangle containing a MapView. Within the MapView, declare a Map to display and an initial Viewpoint.

Rectangle {
    width: 800
    height: 600
     property real scaleFactor: System.displayScaleFactor
     // Map view UI presentation at top
    MapView {
        id: mv
         anchors.fill: parent
        wrapAroundMode: Enums.WrapAroundModeDisabled
         Map {
            BasemapTopographic {}
            initialViewpoint: viewPoint
             FeatureLayer {
                id: featureLayer
                 ServiceFeatureTable {
                    id: featureTable
                    url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/SF311/FeatureServer/0"
                }
            }
        }
         ViewpointCenter {
            id: viewPoint
            center: Point {
                x: -13630484
                y: 4545415
                spatialReference: SpatialReference {
                    wkid: 102100
                }
            }
            targetScale: 300000
        }
    }

Write your app in C++

C++ is all about performance. With the C++ API you can build an app with a powerful computing back-end and develop your UI in C++ using the Qt Widgets module. Writing pure C++ apps was the original option for writing apps when the SDK was originally released, and is still a powerful development pattern. (It is worth noting that the newer pattern using the C++ API with a QML user interface offers C++ performance in the business logic with the UI capabilities of QML across all supported platforms.) C++ is supported for applications running on Linux, macOS, and Windows. For pure C++ apps like these, the map view is implemented as a MapGraphicsView.

Instantiate a MapGraphicsView object.

MapGraphicsView* mv = new MapGraphicsView(this);

Create a map and assign it to the map view.

// create a new basemap instance
    Basemap* basemap = Basemap::imagery(this);
    // create a new map instance
    Map* map = new Map(basemap, this);
    // set map on the map view
    mv->setMap(map);

Write a C++ API app with a QML UI

The MapQuickView class is part of the C++ API. It is an implementation of the map view accessible from QML while harnessing the speed of the C++ API in the business logic. With this approach, you leverage QML's extensive set of UI functionality, flexibility, and visual appeal while providing ArcGIS Runtime capabilities through the C++ API. This is an app pattern that is often recommended by Qt experts, and works on all supported platforms. Note that you cannot use components of the C++ and QML APIs together in the same app.

In your QML code, declare a MapView object and assign it a name. This name is used later to identify and get a reference to this specific instance of the MapView.

// add a mapView component
MapView {
    anchors.fill: parent
    objectName: "mapView"
}

From your C++ code, get a reference to the specific MapView instance using the name you used for its id property. Then, create a Map and associate it with the MapView.

// find QML MapView component
m_mapView = findChild<MapQuickView*>("mapView");
m_mapView->setWrapAroundMode(WrapAroundMode::Disabled);


// Create a map using the topographic basemap
m_map = new Map(Basemap::topographic(this), this);
const Point center = Point(-13630484, 4545415, SpatialReference(102100));
constexpr double scale = 300000.0;
m_map->setInitialViewpoint(Viewpoint(center, scale));


// Set map to map view
m_mapView->setMap(m_map);

Integrate the SDK into an existing app

The SDK can be integrated into an existing Qt app with a couple of steps. The steps vary slightly depending on if the application is a Qt Widgets or Qt Quick based application.

Qt Widgets

Include the esri_runtime_qt project include file (pri) into your project file. You can get this pri file from the SDK installation, under the folder sdk/ideintegration folder. For example, the following syntax includes ArcGIS Runtime into your Qt Widgets application:

include(/pathToSDK/sdk/ideintegration/esri_runtime_qt.pri)

Qt Quick

ArcGIS Runtime supports writing Qt Quick apps either in pure QML code or in a combination of C++ and QML code. This is accomplished by using our QML API or our C++ API, respectively.

Qt Quick - C++ API

To use the C++ API, include the arcgis_runtime_qml_cpp pri file into your project file. You can get this pri file from the SDK installation, under the folder sdk/ideintegration folder. For example, the following syntax includes the ArcGIS Runtime C++ API into your Qt Quick application:

include(/pathToSDK/sdk/ideintegration/arcgis_runtime_qml_cpp.pri)

Once the pri file has been included in your project file, you will need to add the paths of the QML plugins you plan on using into the QML Import Path. For example, you may want to use the ArcGIS Extras plugin or Toolkit module in your app. Adding QML plugins to the QML Import Path can be done by using the QQmlEngine::addImportPath(pathToPlugin); method in C++ code. For example, you can add the ArcGIS Extras QML plugin to the plugin path with the following syntax:

view.engine()->addImportPath("pathToSDK/sdk/macOS/x64/qml");

Similarly, you could add the Toolkit into the plugin path with the following syntax:

view.engine()->addImportPath("pathToSDK/toolkit/Import");

As an alternative, you could instead add an environment variable called QML2_IMPORT_PATH with the paths to the various plugins you wish to use.

After the pri file is included and the import paths are added, import the QML plugin in a QML file by using the import <ModuleIdentifier> <Version.Number> syntax. For example, version 1.1 of ArcGIS Extras could be imported with the following:

import Esri.ArcGISExtras 1.1

Qt Quick - QML API

To use the QML API, include the arcgis_runtime_qml pri file into your project file. You can get this pri file from the SDK installation, under the folder sdk/ideintegration folder. For example, the following syntax includes the ArcGIS Runtime QML API into your Qt QML Quick application:

include(/pathToSDK/sdk/ideintegration/arcgis_runtime_qml.pri)
.

Once the pri file has been included in your project file, you will need to add the paths of the QML plugins you plan on using into the QML Import Path. Because it contains all of the ArcGIS Runtime functionality for this API, add the path to the ArcGIS Runtime QML Plugin. Optionally, you may optionally want to add the import paths to the ArcGIS Extras plugin or the Toolkit. Adding QML plugins to the QML Import Path can be accomplished by using the QQmlEngine::addImportPath(pathToPlugin); method in C++ code. For example, you can add the ArcGIS Runtime QML plugin to the plugin path with the following syntax:

view.engine()->addImportPath("pathToSDK/sdk/macOS/x64/qml");

Similarly, you can add the Toolkit into the plugin path with the following syntax:

view.engine()->addImportPath("pathToSDK/toolkit/Import");

As an alternative, you could instead add an environment variable called QML2_IMPORT_PATH with the paths to the various plugins you wish to use.

After the pri file is included and the import paths are added, import the QML plugin in a QML file by using the import <ModuleIdentifier> <Version.Number> syntax. For example, version 100.1 of ArcGIS Runtime could be imported with the following:

import Esri.ArcGISRuntime 100.1

Additional information

The following Qt resources help further explain how to include project files with qmake and how to add QML plugins into your applications.

Debugging your app

ArcGIS Runtime SDK for Qt is built on top of the Qt Framework, which means you get access to all of the same debugging utilities used with Qt. Here are some helpful tips and tricks for debugging your Qt apps.

Using a web proxy

When debugging ArcGIS Runtime SDK for Qt apps, a web debugging utility is often useful to capture and analyze the HTTP requests that are sent and responses that are returned. Fiddler and Charles are two examples of web debugging utilities used to perform this task. These tools can be used to debug an app by adding the following C++ code in your app: QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, "127.0.0.1", 8888));. This code can be set at runtime, and can either be in your main.cpp, or in some other C++ class. Beyond using a proxy for debugging, QNetworkProxy::setApplicationProxy() can also be used to specify your organization's proxy server. To do this, specify the URL and port of your organization's proxy server. Further information can be found in Qt's QNetworkProxy documentation.