天気情報
Weather Info の例では、Qt Positioning を使用して、Qt Quick の C++ プラグインで、ユーザーの現在位置を使用して Web サービスからローカルコンテンツを取得する方法を示します。
この例で使用するQt Positioning の主要なクラスです:
例の実行
Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。
気象データ・プロバイダー
この例では、いくつかの無関係な気象データ・プロバイダーを使用しています:
使用するプロバイダは実行時に自動的に選択され、選択したプロバイダが利用できない場合は変更できる。ただし、手動で指定することはできません。
注意: すべてのプロバイダーで無料プランが使用され、天気予報のリクエスト量に一定の制限があります。制限を超えると、プロバイダーは一時的に利用できなくなります。すべてのプロバイダーが利用できなくなると、アプリケーションは天気情報を表示できなくなります。この場合、少なくとも1つのプロバイダーが再び利用可能になるまで待つ必要がある。
アプリケーションのデータモデル
この例の重要な部分は、WeatherData
とAppModel
クラスに含まれるアプリケーションのデータモデルです。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(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); }
デフォルトのソースがない場合は、静的な位置を取得し、そのためのウェザーを取得します。しかし、位置ソースがある場合は、その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_ELEMENT とQML_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©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。