Wetter-Infos

Das Beispiel Wetterinfo zeigt, wie man die aktuelle Position des Benutzers verwendet, um lokale Inhalte von einem Webdienst in einem C++-Plugin für Qt Quickunter Verwendung von Qt Positioning.

Schlüssel Qt Positioning Klassen, die in diesem Beispiel verwendet werden:

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel unter Examples aus. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Anbieter von Wetterdaten

Das Beispiel verwendet mehrere nicht miteinander verbundene Wetterdatenanbieter:

Der zu verwendende Anbieter wird zur Laufzeit automatisch ausgewählt und kann geändert werden, wenn der ausgewählte Anbieter nicht verfügbar ist. Er kann jedoch nicht manuell festgelegt werden.

Hinweis: Für alle Anbieter werden kostenlose Tarife verwendet, was gewisse Beschränkungen für die Anzahl der Wetteranfragen mit sich bringt. Wenn diese Grenzen überschritten werden, sind die Anbieter vorübergehend nicht verfügbar. Wenn alle Anbieter nicht mehr verfügbar sind, kann die Anwendung keine Wetterinformationen mehr anzeigen. In diesem Fall muss gewartet werden, bis mindestens einer der Anbieter wieder verfügbar ist.

Datenmodelle der Anwendung

Der wichtigste Teil dieses Beispiels ist das Datenmodell der Anwendung, das in den Klassen WeatherData und AppModel enthalten ist. WeatherData repräsentiert die Wetterinformationen, die aus dem HTTP-Dienst stammen. Es handelt sich um eine einfache Datenklasse, aber wir verwenden Q_PROPERTY, um sie später in QML darzustellen. Sie verwendet auch das Makro QML_ANONYMOUS, wodurch sie in QML erkannt wird.

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 modelliert den Zustand der gesamten Anwendung. Beim Start erhalten wir die Standardposition der Plattform mit 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(); sonstpositionError(QGeoPositionInfoSource::AccessError); }); break; case Qt::PermissionStatus::Denied:            qWarning("Location permission is denied");
            positionFehler(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); }

Wenn keine Standardquelle verfügbar ist, nehmen wir eine statische Position und holen uns das Wetter für diese. Wenn wir jedoch eine Positionsquelle haben, verbinden wir deren positionUpdated()-Signal mit einem Slot auf AppModel und rufen startUpdates() auf, wodurch die regelmäßige Aktualisierung der Geräteposition beginnt.

Wenn eine Positionsaktualisierung empfangen wird, verwenden wir den Längen- und Breitengrad der zurückgegebenen Koordinate, um die Wetterdaten für den angegebenen Standort abzurufen.

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

    if (!d->useGps)
        return;

    requestWeatherByCoordinates();
}

Um die Benutzeroberfläche über diesen Prozess zu informieren, wird das Signal cityChanged() ausgegeben, wenn eine neue Stadt verwendet wird, und das Signal weatherChanged(), wenn eine Wetteraktualisierung erfolgt.

Das Modell verwendet auch das Makro QML_ELEMENT, das es in QML verfügbar macht.

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();
};

Wir verwenden QQmlListProperty für die Wettervorhersageinformationen, die die Wettervorhersage für die nächsten Tage enthalten (die Anzahl der Tage ist anbieterspezifisch). Dies erleichtert den Zugriff auf die Vorhersage über QML.

Benutzerdefinierte Modelle für QML freigeben

Um die Modelle der QML-Oberflächenschicht zugänglich zu machen, verwenden wir die Makros QML_ELEMENT und QML_ANONYMOUS. Weitere Einzelheiten zu diesen Makros finden Sie in der Klassenbeschreibung QQmlEngine.

Um die Typen in QML verfügbar zu machen, müssen wir unseren Build entsprechend aktualisieren.

CMake-Build

Für einen CMake-basierten Build müssen wir das folgende zur CMakeLists.txt hinzufügen:

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

Für einen qmake-Build müssen wir die Datei weatherinfo.pro wie folgt ändern:

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

Instanziierung der Modelle in QML

Schließlich instanziieren wir in der eigentlichen QML die AppModel:

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

Sobald das Modell auf diese Weise instanziiert ist, können wir seine Eigenschaften an anderer Stelle im QML-Dokument verwenden:

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

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

Beispielprojekt @ code.qt.io

© 2025 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.