En esta página

Información meteorológica

El ejemplo Weather Info muestra cómo utilizar la posición actual del usuario para recuperar contenido local de un servicio web en un plugin C++ para Qt Quickutilizando Qt Positioning.

Claves Qt Positioning utilizadas en este ejemplo:

Ejemplo de pantalla de información meteorológica

Ejecución del ejemplo

Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulte Qt Creator: Tutorial: Construir y ejecutar.

Proveedores de datos meteorológicos

El ejemplo utiliza varios proveedores de datos meteorológicos no relacionados:

El proveedor a utilizar se selecciona automáticamente en tiempo de ejecución y puede cambiarse si el proveedor seleccionado no está disponible. Sin embargo, no se puede especificar manualmente.

Nota: Los planes gratuitos se utilizan para todos los proveedores, lo que implica ciertas limitaciones en la cantidad de solicitudes meteorológicas. Si se superan los límites, los proveedores dejan de estar disponibles temporalmente. Cuando todos los proveedores no estén disponibles, la aplicación no podrá mostrar ninguna información meteorológica. En este caso es necesario esperar hasta que al menos uno de los proveedores vuelva a estar disponible.

Modelos de datos de la aplicación

La parte clave de este ejemplo es el modelo de datos de la aplicación, contenido en las clases WeatherData y AppModel. WeatherData representa la información meteorológica tomada del servicio HTTP. Es una clase de datos simple, pero usamos Q_PROPERTY para exponerla bien a QML más tarde. También utiliza la macro QML_ANONYMOUS, que hace que sea reconocida en 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 modela el estado de toda la aplicación. Al inicio, obtenemos la fuente de posición por defecto de la plataforma usando 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::Concedido)  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 no hay ninguna fuente por defecto disponible, tomamos una posición estática y obtenemos el tiempo para esa posición. Si, por el contrario, tenemos una fuente de posición, conectamos su señal positionUpdated() a una ranura de AppModel y llamamos a startUpdates(), que inicia actualizaciones regulares de la posición del dispositivo.

Cuando se recibe una actualización de la posición, utilizamos la longitud y la latitud de la coordenada devuelta para recuperar los datos meteorológicos de la ubicación especificada.

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

    if (!d->useGps)
        return;

    requestWeatherByCoordinates();
}

Para informar a la interfaz de usuario sobre este proceso, se emite la señal cityChanged() cuando se utiliza una nueva ciudad, y la señal weatherChanged() cada vez que se produce una actualización meteorológica.

El modelo también utiliza la macro QML_ELEMENT, que lo hace 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();
};

Para la información meteorológica utilizamos QQmlListProperty, que contiene la previsión del tiempo para los próximos días (el número de días es específico del proveedor). Esto facilita el acceso a la previsión desde QML.

Exponer modelos personalizados a QML

Para exponer los modelos a la capa de interfaz de usuario de QML, utilizamos las macros QML_ELEMENT y QML_ANONYMOUS. Consulte la descripción de la clase QQmlEngine para obtener más detalles sobre estas macros.

Para que los tipos estén disponibles en QML, debemos actualizar nuestra compilación en consecuencia.

Compilación CMake

Para una compilación basada en CMake, necesitamos añadir lo siguiente a 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

Para una compilación qmake, necesitamos modificar el archivo weatherinfo.pro de la siguiente manera:

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

Instanciar los modelos en QML

Finalmente, en el QML actual, instanciamos el AppModel:

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

Una vez instanciado el modelo de esta forma, podemos utilizar sus propiedades en cualquier parte del documento QML:

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

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

Proyecto de ejemplo @ 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.