Auf dieser Seite

Wetterinformationen

Das Beispiel „Wetterinformationen“ zeigt, wie man in einem C++-Plugin für Qt Quick, unter Verwendung von Qt Positioning.

Wichtige Qt Positioning in diesem Beispiel verwendete Klassen:

Beispiel für einen Wetterinformationsbildschirm

Ausführen des Beispiels

Sie können das Beispiel ausführen unter:

Wetterdatenanbieter

Das Beispiel verwendet mehrere unabhängige Wetterdatenanbieter:

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

Hinweis: Für alle Anbieter werdenkostenlose Tarife verwendet, was gewisse Einschränkungen hinsichtlich der Anzahl der Wetterabfragen mit sich bringt. Werden die Limits überschritten, sind die Anbieter vorübergehend nicht verfügbar. Sind alle Anbieter nicht verfügbar, kann die Anwendung keine Wetterinformationen anzeigen. In diesem Fall muss gewartet werden, bis mindestens einer der Anbieter wieder verfügbar ist.

Anwendungsdatenmodelle

Der zentrale Bestandteil dieses Beispiels ist das Datenmodell der Anwendung, das in den Klassen „ WeatherData “ und „ AppModel “ enthalten ist. „ WeatherData “ repräsentiert die vom HTTP-Dienst abgerufenen Wetterinformationen. Es handelt sich um eine einfache Datenklasse, die wir jedoch mithilfe von „ Q_PROPERTY “ später in QML übersichtlich darstellen. Außerdem wird das Makro „ QML_ANONYMOUS “ verwendet, wodurch die Klasse 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 rufen wir die Standard-Positionsquelle der Plattform über ` QGeoPositionInfoSource::createDefaultSource()` ab.

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

Wenn keine Standardquelle verfügbar ist, nehmen wir eine statische Position an und rufen die Wetterdaten dafür ab. Wenn wir jedoch über eine Positionsquelle verfügen, verbinden wir deren Signal ` positionUpdated()` mit einem Slot des ` AppModel ` und rufen ` startUpdates()` auf, wodurch regelmäßige Aktualisierungen der Geräteposition beginnen.

Wenn eine Positionsaktualisierung empfangen wird, verwenden wir den Längen- und Breitengrad der zurückgegebenen Koordinaten, um 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 Vorgang zu informieren, wird das Signal „ cityChanged() “ ausgesendet, wenn eine neue Stadt verwendet wird, und das Signal „ weatherChanged() “, sobald eine Wetteraktualisierung erfolgt.

Das Modell verwendet außerdem das Makro „ QML_ELEMENT “, wodurch es in QML verfügbar ist.

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 ein „ QQmlListProperty “ für die Wettervorhersageinformationen, das die Wettervorhersage für die nächsten Tage enthält (die Anzahl der Tage ist anbieterspezifisch). Dies erleichtert den Zugriff auf die Vorhersage aus QML heraus.

Benutzerdefinierte Modelle für QML verfügbar machen

Um die Modelle für die QML-UI-Ebene verfügbar zu machen, verwenden wir die Makros „ QML_ELEMENT “ und „ QML_ANONYMOUS “. Weitere Informationen zu diesen Makros finden Sie in der Klassenbeschreibung von „ QQmlEngine “.

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

CMake-Build

Für einen CMake-basierten Build müssen wir Folgendes zur Datei „ 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 anpassen:

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

Instanzen der Modelle in QML erstellen

Schließlich instanziieren wir in der eigentlichen QML-Datei 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

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