Sur cette page

Info météo

L'exemple Weather Info montre comment utiliser la position actuelle de l'utilisateur pour récupérer le contenu local d'un service web dans un plugin C++ pour Qt Quicken utilisant Qt Positioning.

Les classes Qt Positioning utilisées dans cet exemple :

Exemple d'écran d'information météorologique

Exécution de l'exemple

Pour exécuter l'exemple à partir de Qt Creatorouvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.

Fournisseurs de données météorologiques

L'exemple utilise plusieurs fournisseurs de données météorologiques non apparentés :

Le fournisseur à utiliser est sélectionné automatiquement au moment de l'exécution et peut être modifié si le fournisseur sélectionné n'est pas disponible. Cependant, il ne peut pas être spécifié manuellement.

Note : Les plans gratuits sont utilisés pour tous les fournisseurs, ce qui implique certaines limitations sur le nombre de requêtes météorologiques. Si les 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éorologique. Dans ce cas, il est nécessaire d'attendre qu'au moins un des fournisseurs redevienne disponible.

Modèles de données de l'application

La partie 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 provenant du service HTTP. Il s'agit d'une simple classe de données, mais nous utilisons Q_PROPERTY pour l'exposer joliment à QML par la suite. Elle utilise également la macro QML_ANONYMOUS, ce qui lui permet d'être reconnue par 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'application entière. Au démarrage, nous obtenons la source de position par défaut de la plateforme en utilisant 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() ; elsepositionError(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 la météo pour celle-ci. Cependant, si nous disposons d'une source de position, nous connectons son signal positionUpdated() à un emplacement sur AppModel et appelons startUpdates(), qui commence les mises à jour régulières de la position de l'appareil.

Lorsqu'une mise à jour de la position est reçue, nous utilisons la longitude et la latitude de la coordonnée renvoyée pour récupérer les données météorologiques pour 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 utilisée, et le signal weatherChanged() à chaque fois qu'une mise à jour météorologique a lieu.

Le modèle utilise également la macro QML_ELEMENT, qui le 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 site QQmlListProperty pour les informations sur les prévisions météorologiques, qui contient les prévisions météorologiques pour les jours suivants (le nombre de jours est spécifique au fournisseur). Il est ainsi facile d'accéder aux prévisions à partir de 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. Voir la description de la classe QQmlEngine pour plus de détails sur ces macros.

Pour rendre les types disponibles en QML, nous devons mettre à jour notre construction en conséquence.

Construction CMake

Pour une construction basée sur CMake, nous devons ajouter ce qui suit à l'adresse 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
)
qmake Build

Pour une compilation qmake, nous devons 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 en QML

Enfin, dans le QML actuel, nous instançons le modèle AppModel:

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

Une fois le modèle ainsi instancié, 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 @ 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.