Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Classes principales  ·  Annotées  ·  Classes groupées  ·  Modules  ·  Fonctions  · 

Weather Info (C++/QML)

The Weather Info example shows how to use the user's current position to retrieve local content from a web service in a C++ plugin for QML.

Key Qt Location classes used in this example:

The key part of this example is the application's data model, contained in the WeatherData and AppModel classes. WeatherData represents the weather information taken from the HTTP service. It is a simple data class, but we give it Q_PROPERTies to expose it nicely to QML, later.

 class WeatherData : public QObject {
     Q_OBJECT
     Q_PROPERTY(QString dayOfWeek
                READ dayOfWeek WRITE setDayOfWeek
                NOTIFY dataChanged)
     Q_PROPERTY(QString weather
                READ weather WRITE setWeather
                NOTIFY dataChanged)
     Q_PROPERTY(QString weatherDesc
                READ weatherDesc WRITE setWeatherDesc
                NOTIFY dataChanged)
     Q_PROPERTY(QString tempString
                READ tempString WRITE setTempString
                NOTIFY dataChanged)

 public:
     explicit WeatherData(QObject *parent = 0);
     WeatherData(const WeatherData &other);

     const WeatherData &operator=(const WeatherData &other);

     QString dayOfWeek() const;
     QString weather() const;
     QString weatherDesc() const;
     QString tempString() const;

     void setDayOfWeek(QString value);
     void setWeather(QString value);
     void setWeatherDesc(QString value);
     void setTempString(QString value);

 signals:
     void dataChanged();
 };

AppModel models the state of the entire application. At startup, the application first begins by waiting for network connectivity. We do this using the QNetworkConfigurationManager and QNetworkSession family of C++ APIs.

 AppModel::AppModel(QObject *parent) :
         QObject(parent),
         d(new AppModelPrivate)
 {
     // make sure we have an active network session
     d->nam = new QNetworkAccessManager(this);

     QNetworkConfigurationManager ncm;
     d->ns = new QNetworkSession(ncm.defaultConfiguration(), this);
     connect(d->ns, SIGNAL(opened()), this, SLOT(networkSessionOpened()));
     // the session may be already open. if it is, run the slot directly
     if (d->ns->isOpen())
         this->networkSessionOpened();
     // tell the system we want network
     d->ns->open();
 }

Once the network session is open, we proceed to get the platform's default position source using QGeoPositionInfo::createDefaultSource()

 void AppModel::networkSessionOpened()
 {
     d->src = QGeoPositionInfoSource::createDefaultSource(this);

     if (d->src) {
         d->useGps = true;
         connect(d->src, SIGNAL(positionUpdated(QGeoPositionInfo)),
                 this, SLOT(positionUpdated(QGeoPositionInfo)));
         d->src->startUpdates();
     } else {
         d->useGps = false;
         d->city = "Brisbane";
         emit cityChanged();
         this->refreshWeather();
     }
 }

If no default source is available, we take a static location and fetch weather for that. If, however, we do have a position source, we connect its positionUpdated() signal to a slot on the AppModel and call startUpdates(), which begins regular updates of device position.

When a position update is received, we use the longitude and latitude of the returned coordinate to retrieve the current "city" name for use in the weather lookup.

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

     if (!(d->useGps))
         return;

     QString latitude, longitude;
     longitude.setNum(d->coord.longitude());
     latitude.setNum(d->coord.latitude());

To inform the UI about this process, the cityChanged() signal is emitted when a new city is used, and the weatherChanged() signal whenever a weather update occurs.

 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)

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

 };

We use a QQmlListProperty for the weather forecast information, which contains the next 4 days of forecast weather. This makes it easy to access from QML.

To expose these to the QML UI layer, we use the qmlRegisterType() function. We call this once for each type we wish to register, before loading the actual QML file.

 #include "appmodel.h"

 int main(int argc, char *argv[])
 {
     QGuiApplication application(argc, argv);

     qmlRegisterType<WeatherData>("WeatherInfo", 1, 0, "WeatherData");
     qmlRegisterType<AppModel>("WeatherInfo", 1, 0, "AppModel");

     const QString mainQmlApp = QLatin1String("qrc:///weatherinfo.qml");
     QQuickView view;
     view.setSource(QUrl(mainQmlApp));
     view.setResizeMode(QQuickView::SizeRootObjectToView);

     QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit()));
     view.setGeometry(QRect(100, 100, 360, 640));
     view.show();
     return application.exec();
 }

Finally, in the actual QML, we instantiate the AppModel.

 import WeatherInfo 1.0

 Item {
     id: window
     AppModel {
         id: model
         onReadyChanged: {
             if (model.ready)
                 window.state = "ready"
             else
                 window.state = "loading"
         }
     }
 }

Once instantiated like this, we can use its properties elsewhere in the QML document:

             BigForecastIcon {
                 id: current

                 width: main.width - 3
                 height: 2 * (main.height - 25 - 12) / 3

                 weather: (model.hasValidWeather
                           ? model.weather.weather
                           : "sunny")
             }

Files:

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt 5.0-snapshot
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !
 
 
 
 
Partenaires

Hébergement Web