Sur cette page

Informations météo

L'exemple « Informations météo » montre comment utiliser la position actuelle de l'utilisateur pour récupérer du contenu local à partir d'un service Web dans un plugin C++ pour Qt Quick, à l'aide de Qt Positioning.

Les Qt Positioning utilisées dans cet exemple :

Exemple d'écran d'informations météo

Exécution de l'exemple

Vous pouvez exécuter l'exemple à partir de :

Fournisseurs de données météorologiques

L'exemple utilise plusieurs fournisseurs de données météorologiques sans lien entre eux :

Le fournisseur à utiliser est sélectionné automatiquement lors de l'exécution et peut être modifié si le fournisseur sélectionné n'est pas disponible. Il ne peut toutefois pas être spécifié manuellement.

Remarque : tous les fournisseurs utilisent des formulesgratuites , ce qui implique certaines limitations quant au nombre de requêtes météo. Si ces limites sont dépassées, les fournisseurs deviennent temporairement indisponibles. Lorsque tous les fournisseurs sont indisponibles, l'application ne peut afficher aucune information météo. Dans ce cas, il est nécessaire d'attendre qu'au moins l'un des fournisseurs redevienne disponible.

Modèles de données de l’application

L'élément clé de cet exemple est le modèle de données de l'application, contenu dans les classes ` WeatherData ` et ` AppModel `. ` WeatherData ` représente les informations météorologiques récupérées auprès du service HTTP. Il s'agit d'une classe de données simple, mais nous utilisons ` Q_PROPERTY ` pour l'exposer correctement dans QML par la suite. Elle utilise également la macro ` QML_ANONYMOUS `, qui permet de la reconnaître dans QML.

class WeatherData : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString dayOfWeek
               READ dayOfWeek WRITE setDayOfWeek
               NOTIFY dataChanged)
    Q_PROPERTY(QString weatherIcon
               READ weatherIcon WRITE setWeatherIcon
               NOTIFY dataChanged)
    Q_PROPERTY(QString weatherDescription
               READ weatherDescription WRITE setWeatherDescription
               NOTIFY dataChanged)
    Q_PROPERTY(QString temperature
               READ temperature WRITE setTemperature
               NOTIFY dataChanged)
    QML_ANONYMOUS

public:
    explicit WeatherData(QObject *parent = 0);
    WeatherData(const WeatherData &other);
    WeatherData(const WeatherInfo &other);

    QString dayOfWeek() const;
    QString weatherIcon() const;
    QString weatherDescription() const;
    QString temperature() const;

    void setDayOfWeek(const QString &value);
    void setWeatherIcon(const QString &value);
    void setWeatherDescription(const QString &value);
    void setTemperature(const QString &value);

signals:
    void dataChanged();
};

AppModel modélise l’état de l’ensemble de l’application. Au démarrage, nous récupérons la source de position par défaut de la plateforme à l’aide de QGeoPositionInfoSource::createDefaultSource().

AppModel::AppModel(QObject*parent) :
        QObject(parent),
        d(new AppModelPrivate)
{
    d->src = QGeoPositionInfoSource::createDefaultSource(this);

    if (d->src) {
        d->useGps = true;
        connect(d->src, &QGeoPositionInfoSource::positionUpdated,
                this, &AppModel::positionUpdated);
        connect(d->src, &QGeoPositionInfoSource::errorOccurred,
                this, &AppModel::positionError);
#if QT_CONFIG(permissions)
        QLocationPermission permission;
        permission.setAccuracy(QLocationPermission::Precise);
        permission.setAvailability(QLocationPermission::WhenInUse);

        switch (qApp->checkPermission(permission)) {
        case Qt::PermissionStatus::Undetermined:
            qApp->requestPermission(permission, [this] (const QPermission& permission) {
                if (permission.status()== Qt::PermissionStatus::Granted)
                    d->src->startUpdates();
                else
                    positionError(QGeoPositionInfoSource::AccessError);
            });
            break;
        case Qt::PermissionStatus::Denied :
            qWarning("Location permission is denied");
            positionError(QGeoPositionInfoSource::AccessError);
            break;
        case Qt::PermissionStatus::Granted :
            d->src->startUpdates();
            break;
        }
#else
        d->src->startUpdates();
#endif
    } else {
        d->useGps = false;
        d->city = "Brisbane";
        emit cityChanged();
        requestWeatherByCity();
    }

    QTimer*refreshTimer = new QTimer(this);
    connect(refreshTimer, &QTimer::timeout, this, &AppModel::refreshWeather);
    using namespace std::chrono;
    refreshTimer->start(60s);
}

Si aucune source par défaut n’est disponible, nous prenons une position statique et récupérons les données météo correspondantes. Si, en revanche, nous disposons d’une source de position, nous connectons son signal positionUpdated() à un slot de l’ AppModel et appelons startUpdates(), ce qui déclenche des mises à jour régulières de la position de l’appareil.

Lorsqu’une mise à jour de position est reçue, nous utilisons la longitude et la latitude des coordonnées renvoyées pour récupérer les données météorologiques correspondant à l’emplacement spécifié.

void AppModel::positionUpdated(QGeoPositionInfo gpsPos)
{
    d->coord = gpsPos.coordinate();

    if (!d->useGps)
        return;

    requestWeatherByCoordinates();
}

Pour informer l’interface utilisateur de ce processus, le signal ` cityChanged() ` est émis lorsqu’une nouvelle ville est sélectionnée, et le signal ` weatherChanged() ` chaque fois qu’une mise à jour météo a lieu.

Le modèle utilise également la macro ` QML_ELEMENT `, ce qui la rend disponible en QML.

class AppModel : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool ready
               READ ready
               NOTIFY readyChanged)
    Q_PROPERTY(bool hasSource
               READ hasSource
               NOTIFY readyChanged)
    Q_PROPERTY(bool hasValidCity
               READ hasValidCity
               NOTIFY cityChanged)
    Q_PROPERTY(bool hasValidWeather
               READ hasValidWeather
               NOTIFY weatherChanged)
    Q_PROPERTY(bool useGps
               READ useGps WRITE setUseGps
               NOTIFY useGpsChanged)
    Q_PROPERTY(QString city
               READ city WRITE setCity
               NOTIFY cityChanged)
    Q_PROPERTY(WeatherData *weather
               READ weather
               NOTIFY weatherChanged)
    Q_PROPERTY(QQmlListProperty<WeatherData> forecast
               READ forecast
               NOTIFY weatherChanged)
    QML_ELEMENT

public:
    explicit AppModel(QObject *parent = 0);
    ~AppModel();

    bool ready() const;
    bool hasSource() const;
    bool useGps() const;
    bool hasValidCity() const;
    bool hasValidWeather() const;
    void setUseGps(bool value);

    QString city() const;
    void setCity(const QString &value);

    WeatherData *weather() const;
    QQmlListProperty<WeatherData> forecast() const;

public slots:
    Q_INVOKABLE void refreshWeather();

signals:
    void readyChanged();
    void useGpsChanged();
    void cityChanged();
    void weatherChanged();
};

Nous utilisons un QQmlListProperty pour les informations de prévisions météorologiques, qui contient les prévisions pour les prochains jours (le nombre de jours dépend du fournisseur). Cela facilite l’accès aux prévisions depuis QML.

Exposer des modèles personnalisés à QML

Pour exposer les modèles à la couche d’interface utilisateur QML, nous utilisons les macros QML_ELEMENT et QML_ANONYMOUS. Reportez-vous à la description de la classe QQmlEngine pour plus de détails sur ces macros.

Pour que ces types soient disponibles dans QML, nous devons mettre à jour notre processus de compilation en conséquence.

Compilation CMake

Pour une compilation basée sur CMake, nous devons ajouter ce qui suit au fichier ` CMakeLists.txt` :

qt_add_qml_module(weatherinfo
    URI Weather
    VERSION 1.0
    SOURCES
        appmodel.cpp appmodel.h
        openmeteobackend.cpp openmeteobackend.h
        openweathermapbackend.cpp openweathermapbackend.h
        providerbackend.cpp providerbackend.h
        weatherapibackend.cpp weatherapibackend.h
    QML_FILES
        BigForecastIcon.qml
        ForecastIcon.qml
        WeatherIcon.qml
        WeatherInfo.qml
    RESOURCES
        icons/weather-few-clouds.svg
        icons/weather-fog.svg
        icons/weather-haze.svg
        icons/weather-icy.svg
        icons/weather-overcast.svg
        icons/weather-showers.svg
        icons/weather-sleet.svg
        icons/weather-snow.svg
        icons/weather-storm.svg
        icons/weather-sunny-very-few-clouds.svg
        icons/weather-sunny.svg
        icons/weather-thundershower.svg
        icons/weather-showers-scattered.svg
        icons/waypoint.svg
)
Compilation avec qmake

Pour une compilation avec qmake, il faut modifier le fichier weatherinfo.pro de la manière suivante :

CONFIG += qmltypes
QML_IMPORT_NAME = Weather
QML_IMPORT_MAJOR_VERSION = 1

qml_resources.files = \
    qmldir \
    BigForecastIcon.qml \
    ForecastIcon.qml \
    WeatherIcon.qml \
    WeatherInfo.qml \
    icons/weather-few-clouds.svg \
    icons/weather-fog.svg \
    icons/weather-haze.svg \
    icons/weather-icy.svg \
    icons/weather-overcast.svg \
    icons/weather-showers.svg \
    icons/weather-showers-scattered.svg \
    icons/weather-sleet.svg \
    icons/weather-snow.svg \
    icons/weather-storm.svg \
    icons/weather-sunny-very-few-clouds.svg \
    icons/weather-sunny.svg \
    icons/weather-thundershower.svg \
    icons/waypoint.svg

qml_resources.prefix = /qt/qml/Weather

RESOURCES += qml_resources

Instancier les modèles dans QML

Enfin, dans le code QML proprement dit, nous instancions l'AppModel:

Window {
    id: window
    AppModel {
        id: appModel
        onReadyChanged: {
            if (appModel.ready)
                statesItem.state = "ready"
            else
                statesItem.state = "loading"
        }
    }
}

Une fois le modèle instancié de cette manière, nous pouvons utiliser ses propriétés ailleurs dans le document QML :

    BigForecastIcon {
        id: current
        Layout.fillWidth: true
        Layout.fillHeight: true

        weatherIcon: (appModel.hasValidWeather
                      ? appModel.weather.weatherIcon
                      : "sunny")
    }

Exemple de projet sur code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.