天気情報

のC++プラグインで、ユーザーの現在位置を利用してウェブ・サービスからローカル・コンテンツを取得する方法を紹介します。 Qt Quickを使用しています。 Qt Positioning.

キー Qt Positioningこの例で使用されている

例の実行

から例を実行するには Qt Creatorからサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Exampleを参照してください。

気象データ・プロバイダー

この例では、いくつかの無関係な気象データ・プロバイダーを使用しています:

使用するプロバイダは実行時に自動的に選択され、選択したプロバイダが利用できない場合は変更できます。ただし、手動で指定することはできません。

注意: 無料プランはすべてのプロバイダーで使用され、天候リクエストの量に一定の制限があります。制限を超えると、プロバイダーは一時的に利用できなくなります。すべてのプロバイダーが利用できなくなると、アプリケーションは天気情報を表示できなくなります。この場合、少なくとも1つのプロバイダーが再び利用可能になるまで待つ必要があります。

アプリケーション・データ・モデル

この例で重要なのは、WeatherDataAppModel クラスに含まれるアプリケーションのデータモデルです。WeatherData はHTTPサービスから取得した天気情報を表します。これは単純なデータクラスですが、後でQMLにうまく公開するためにQ_PROPERTY 。また、QML_ANONYMOUS マクロを使用し、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 はアプリケーション全体の状態をモデル化します。起動時に、 ()を使ってプラットフォームのデフォルトの位置ソースを取得します。QGeoPositionInfoSource::createDefaultSource

AppModel::AppModel(QObject*parent) :   QObject(親),d(newAppModelPrivate) { 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)        QLocationPermissionpermission; permission.setAccuracy(QLocationPermission::Precise); permission.setAvailability(QLocationPermission::WhenInUse);switch(qApp->checkPermission(permission)) {caseQt::PermissionStatus::Undetermined: qApp->requestPermission(permission, [this](constQPermission(&permission) {if(permission.status()==) Qt::PermissionStatus::Granted) d->src->startUpdates();elsepositionError(QGeoPositionInfoSource::AccessError); });break;caseQt::PermissionStatus::Denied:            qWarning("Location permission is denied");
            positionError(QGeoPositionInfoSource::AccessError);break;caseQt::PermissionStatus::Granted: d->src->startUpdates();break; }#else d->src->startUpdates();#endif}else{ d->useGps = false; d->city = "Brisbane"; cityChanged(); requestWeatherByCity(); }.QTimer*refreshTimer = newQTimer(this); connect(refreshTimer, &QTimer::timeout, this, &AppModel::refreshWeather);using namespacestd::chrono; refreshTimer->start(60s); }

デフォルトのソースがない場合は、静的な位置を取得し、その位置の天気を取得します。しかし、位置ソースがある場合は、そのpositionUpdated() シグナルをAppModel のスロットに接続し、startUpdates() を呼び出します。

位置の更新を受信すると、返された座標の経度と緯度を使用して、指定された場所の気象データを取得する。

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

    if (!d->useGps)
        return;

    requestWeatherByCoordinates();
}

このプロセスをUIに通知するために、新しい都市が使用されるときはcityChanged() 、天候の更新が発生するときはweatherChanged()

また、このモデルはQML_ELEMENT マクロを使用しており、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();
};

天気予報情報にはQQmlListProperty を使用しています。この情報には、今後数日間の天気予報が含まれています(日数はプロバイダによって異なります)。これにより、QMLから天気予報に簡単にアクセスすることができます。

カスタムモデルをQMLに公開する

モデルをQMLのUIレイヤーに公開するために、QML_ELEMENTQML_ANONYMOUS マクロを使います。これらのマクロの詳細については、QQmlEngine クラスの説明を参照してください。

QMLで型を利用できるようにするためには、それに応じてビルドを更新する必要があります。

CMakeビルド

CMakeベースのビルドでは、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ビルド

qmakeビルドの場合は、weatherinfo.pro

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

QMLでモデルをインスタンス化する

最後に、実際のQMLの中で、AppModel をインスタンス化します:

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

このようにモデルがインスタンス化されると、QMLドキュメント内の他の場所でそのプロパティを使うことができるようになります:

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

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

プロジェクトの例 @ 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.