diff options
author | Alex Wilson <alex.wilson@nokia.com> | 2011-12-08 16:53:43 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-13 07:29:15 +0100 |
commit | 78ebb1fb73b957ed8a7bfcd92dcf738bac691d4c (patch) | |
tree | c23de8d6d3d588e625b51e24050650af6a7bafa7 | |
parent | 70cbbc2ea11afc41d2753e92c5dd785c66e70d1b (diff) | |
download | qtlocation-78ebb1fb73b957ed8a7bfcd92dcf738bac691d4c.tar.gz |
QML-based WeatherInfo example, to demonstrate location position APIs
* Unlike the old WeatherInfo, uses a QML-based UI, but still
all c++ backend (model class approach)
* Also PNG icons, so no dep on QtSVG
* Includes a qdoc overview of the example with highlight snippets
Change-Id: Ib84a83177aaff220d728c6e54c9586ac9f2ea988
Reviewed-by: David Laing <david.laing@nokia.com>
25 files changed, 1326 insertions, 2 deletions
diff --git a/doc/src/examples/qtlocation-examples.qdoc b/doc/src/examples/qtlocation-examples.qdoc index ba9864ab..811c870f 100644 --- a/doc/src/examples/qtlocation-examples.qdoc +++ b/doc/src/examples/qtlocation-examples.qdoc @@ -46,7 +46,6 @@ \ingroup qtlocation-examples */ - /*! \example maps \title Maps diff --git a/doc/src/examples/weatherinfo.qdoc b/doc/src/examples/weatherinfo.qdoc new file mode 100644 index 00000000..2cb3daf1 --- /dev/null +++ b/doc/src/examples/weatherinfo.qdoc @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example weatherinfo + \title Weather Info Example + + \brief The Weather Info example shows the use of the C++ Location API in combination + with a weather service and a QML UI to display the data. + + \ingroup qtlocation-examples + + 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. + + \snippet examples/weatherinfo/appmodel.h 0 + \snippet examples/weatherinfo/appmodel.h 1 + + 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. + + \snippet examples/weatherinfo/appmodel.cpp 0 + \snippet examples/weatherinfo/appmodel.cpp 1 + + Once the network session is open, we proceed to get the platform's + default position source using QGeoPositionInfo::createDefaultSource() + + \snippet examples/weatherinfo/appmodel.cpp 2 + + 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. + + \snippet examples/weatherinfo/appmodel.cpp 3 + + 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. + + \snippet examples/weatherinfo/appmodel.h 2 + \snippet examples/weatherinfo/appmodel.h 3 + \snippet examples/weatherinfo/appmodel.h 4 + + We use a QDeclarativeListProperty 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. + + \snippet examples/weatherinfo/main.cpp 0 + \snippet examples/weatherinfo/main.cpp 1 + + Finally, in the actual QML, we instantiate the AppModel. + + \snippet examples/weatherinfo/weatherinfo.qml 0 + \snippet examples/weatherinfo/weatherinfo.qml 1 + \snippet examples/weatherinfo/weatherinfo.qml 2 + + Once instantiated like this, we can use its properties elsewhere in the + QML document: + + \snippet examples/weatherinfo/weatherinfo.qml 3 + \snippet examples/weatherinfo/weatherinfo.qml 4 + +*/ diff --git a/examples/examples.pro b/examples/examples.pro index 38d2cf30..28cabc0e 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS += declarative logfilepositionsource +SUBDIRS += declarative logfilepositionsource weatherinfo diff --git a/examples/weatherinfo/appmodel.cpp b/examples/weatherinfo/appmodel.cpp new file mode 100644 index 00000000..38ef2b3f --- /dev/null +++ b/examples/weatherinfo/appmodel.cpp @@ -0,0 +1,477 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "appmodel.h" + +#include <qgeopositioninfosource.h> +#include <qgeosatelliteinfosource.h> +#include <qnmeapositioninfosource.h> +#include <qgeopositioninfo.h> +#include <qnetworkconfigmanager.h> +#include <qnetworksession.h> + +#include <QSignalMapper> +#include <QXmlStreamReader> +#include <QRegExp> +#include <QStringList> + +WeatherData::WeatherData(QObject *parent) : + QObject(parent) +{ +} + +WeatherData::WeatherData(const WeatherData &other) : + QObject(0), + m_dayOfWeek(other.m_dayOfWeek), + m_weather(other.m_weather), + m_weatherDesc(other.m_weatherDesc), + m_tempString(other.m_tempString) +{ +} + +const WeatherData &WeatherData::operator=(const WeatherData &other) +{ + m_dayOfWeek = other.m_dayOfWeek; + m_weather = other.m_weather; + m_weatherDesc = other.m_weatherDesc; + m_tempString = other.m_tempString; + return *this; +} + +QString WeatherData::dayOfWeek() const +{ + return m_dayOfWeek; +} + +QString WeatherData::weather() const +{ + return m_weather; +} + +QString WeatherData::weatherDesc() const +{ + return m_weatherDesc; +} + +QString WeatherData::tempString() const +{ + return m_tempString; +} + +void WeatherData::setDayOfWeek(QString value) +{ + m_dayOfWeek = value; + emit dataChanged(); +} + +void WeatherData::setWeather(QString value) +{ + m_weather = value; + emit dataChanged(); +} + +void WeatherData::setWeatherDesc(QString value) +{ + m_weatherDesc = value; + emit dataChanged(); +} + +void WeatherData::setTempString(QString value) +{ + m_tempString = value; + emit dataChanged(); +} + +class AppModelPrivate +{ +public: + QGeoPositionInfoSource *src; + QGeoCoordinate coord; + QString city; + QNetworkAccessManager *nam; + QNetworkSession *ns; + WeatherData now; + QList<WeatherData*> forecast; + QDeclarativeListProperty<WeatherData> *fcProp; + QSignalMapper *geoReplyMapper; + QSignalMapper *weatherReplyMapper; + bool ready; + bool useGps; + + AppModelPrivate() : + src(NULL), + nam(NULL), + ns(NULL), + fcProp(NULL), + ready(false), + useGps(true) + {} +}; + +static void forecastAppend(QDeclarativeListProperty<WeatherData> *prop, WeatherData *val) +{ + Q_UNUSED(val); + Q_UNUSED(prop); +} + +static WeatherData *forecastAt(QDeclarativeListProperty<WeatherData> *prop, int index) +{ + AppModelPrivate *d = static_cast<AppModelPrivate*>(prop->data); + return d->forecast.at(index); +} + +static int forecastCount(QDeclarativeListProperty<WeatherData> *prop) +{ + AppModelPrivate *d = static_cast<AppModelPrivate*>(prop->data); + return d->forecast.size(); +} + +//! [0] +AppModel::AppModel(QObject *parent) : + QObject(parent), + d(new AppModelPrivate) +{ +//! [0] + d->fcProp = new QDeclarativeListProperty<WeatherData>(this, d, + forecastAppend, + forecastCount, + forecastAt); + + d->geoReplyMapper = new QSignalMapper(this); + d->weatherReplyMapper = new QSignalMapper(this); + + connect(d->geoReplyMapper, SIGNAL(mapped(QObject*)), + this, SLOT(handleGeoNetworkData(QObject*))); + connect(d->weatherReplyMapper, SIGNAL(mapped(QObject*)), + this, SLOT(handleWeatherNetworkData(QObject*))); + +//! [1] + // 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(); +} +//! [1] + +AppModel::~AppModel() +{ + d->ns->close(); + if (d->src) + d->src->stopUpdates(); + delete d; +} + +//! [2] +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(); + } +} +//! [2] + +//! [3] +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()); +//! [3] + QUrl url("http://maps.google.com/maps/geo"); + url.addEncodedQueryItem("q", QUrl::toPercentEncoding(latitude + "," + longitude)); + url.addEncodedQueryItem("output", QUrl::toPercentEncoding("xml")); + + QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); + // connect up the signal right away + d->geoReplyMapper->setMapping(rep, rep); + connect(rep, SIGNAL(finished()), + d->geoReplyMapper, SLOT(map())); + // it might have finished though while we were connecting it + // if so, pass it straight on + if (rep->isFinished()) + this->handleGeoNetworkData(rep); +} + +void AppModel::handleGeoNetworkData(QObject *replyObj) +{ + QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(replyObj); + if (!networkReply) + return; + + if (!networkReply->error()) { + QString xml = QString::fromUtf8(networkReply->readAll()); + + int start = xml.indexOf("<LocalityName>"); + int end = xml.indexOf("</LocalityName>"); + + QString city = xml.mid(start + 14, end - start - 14); + if (city != d->city) { + emit cityChanged(); + this->refreshWeather(); + } + } + networkReply->deleteLater(); +} + +void AppModel::refreshWeather() +{ + QUrl url("http://www.google.com/ig/api"); + url.addEncodedQueryItem("hl", "en"); + url.addEncodedQueryItem("weather", QUrl::toPercentEncoding(d->city)); + + QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); + // connect up the signal right away + d->weatherReplyMapper->setMapping(rep, rep); + connect(rep, SIGNAL(finished()), + d->weatherReplyMapper, SLOT(map())); + // it might have finished though while we were connecting it + // if so, pass it straight on + if (rep->isFinished()) + this->handleWeatherNetworkData(rep); +} + +static QString google2name(QString weather) +{ + static QHash<QString, QString> conv; + if (conv.isEmpty()) { + conv["mostly_cloudy"] = "few-clouds"; + conv["cloudy"] = "overcast"; + conv["mostly_sunny"] = "sunny-very-few-clouds"; + conv["partly_cloudy"] = "sunny-very-few-clouds"; + conv["sunny"] = "sunny"; + conv["flurries"] = "snow"; + conv["fog"] = "fog"; + conv["haze"] = "haze"; + conv["icy"] = "icy"; + conv["sleet"] = "sleet"; + conv["chance_of_sleet"] = "sleet"; + conv["snow"] = "snow"; + conv["chance_of_snow"] = "snow"; + conv["mist"] = "showers"; + conv["rain"] = "showers"; + conv["chance_of_rain"] = "showers"; + conv["storm"] = "storm"; + conv["chance_of_storm"] = "storm"; + conv["thunderstorm"] = "thundershower"; + conv["chance_of_tstorm"] = "thundershower"; + } + QRegExp regex("([\\w]+).gif$"); + if (regex.indexIn(weather) != -1) { + QString i = regex.cap(); + i = i.left(i.length() - 4); + QString name = conv.value(i); + if (!name.isEmpty()) + return name; + } + return QString(); +} + +// little helper for repetitive code +#define GET_DATA_ATTR xml.attributes().value("data").toString() + +void AppModel::handleWeatherNetworkData(QObject *replyObj) +{ + QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(replyObj); + if (!networkReply) + return; + + if (!networkReply->error()) { + QString xmlData = QString::fromUtf8(networkReply->readAll()); + + foreach (WeatherData *inf, d->forecast) + delete inf; + d->forecast.clear(); + + QXmlStreamReader xml(xmlData); + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.name() == "current_conditions") { + while (!xml.atEnd()) { + xml.readNext(); + if (xml.name() == "current_conditions") + break; + if (xml.tokenType() == QXmlStreamReader::StartElement) { + if (xml.name() == "condition") { + d->now.setWeatherDesc(GET_DATA_ATTR); + } else if (xml.name() == "icon") { + d->now.setWeather(google2name(GET_DATA_ATTR)); + } else if (xml.name() == "temp_f") { + d->now.setTempString(GET_DATA_ATTR + QChar(176)); + } + } + } + } + + if (xml.name() == "forecast_conditions") { + WeatherData *cur = NULL; + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.name() == "forecast_conditions") { + if (cur) { + d->forecast.append(cur); + } + break; + } else if (xml.tokenType() == QXmlStreamReader::StartElement) { + if (!cur) + cur = new WeatherData(); + if (xml.name() == "day_of_week") { + cur->setDayOfWeek(GET_DATA_ATTR); + } else if (xml.name() == "icon") { + cur->setWeather(google2name(GET_DATA_ATTR)); + } else if (xml.name() == "low") { + QString v = cur->tempString(); + QStringList parts = v.split("/"); + if (parts.size() >= 1) + parts.replace(0, GET_DATA_ATTR + QChar(176)); + if (parts.size() == 0) + parts.append(GET_DATA_ATTR + QChar(176)); + + cur->setTempString(parts.join("/")); + } else if (xml.name() == "high") { + QString v = cur->tempString(); + QStringList parts = v.split("/"); + if (parts.size() == 2) + parts.replace(1, GET_DATA_ATTR + QChar(176)); + if (parts.size() == 0) + parts.append(""); + if (parts.size() == 1) + parts.append(GET_DATA_ATTR + QChar(176)); + + cur->setTempString(parts.join("/")); + } + } + } + } + } + + if (!(d->ready)) { + d->ready = true; + emit readyChanged(); + } + + emit weatherChanged(); + } + networkReply->deleteLater(); +} + +bool AppModel::hasValidCity() const +{ + return (!(d->city.isEmpty()) && d->city.size() > 1 && d->city != ""); +} + +bool AppModel::hasValidWeather() const +{ + return hasValidCity() && (!(d->now.weather().isEmpty()) && + (d->now.weather().size() > 1) && + d->now.weather() != ""); +} + +WeatherData *AppModel::weather() const +{ + return &(d->now); +} + +QDeclarativeListProperty<WeatherData> AppModel::forecast() const +{ + return *(d->fcProp); +} + +bool AppModel::ready() const +{ + return d->ready; +} + +bool AppModel::hasSource() const +{ + return (d->src != NULL); +} + +bool AppModel::useGps() const +{ + return d->useGps; +} + +void AppModel::setUseGps(bool value) +{ + d->useGps = value; + if (value) { + d->city = ""; + emit cityChanged(); + emit weatherChanged(); + } + emit useGpsChanged(); +} + +QString AppModel::city() const +{ + return d->city; +} + +void AppModel::setCity(const QString &value) +{ + d->city = value; + emit cityChanged(); + this->refreshWeather(); +} diff --git a/examples/weatherinfo/appmodel.h b/examples/weatherinfo/appmodel.h new file mode 100644 index 00000000..6f633026 --- /dev/null +++ b/examples/weatherinfo/appmodel.h @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef APPMODEL_H +#define APPMODEL_H + +#include <QtCore/QObject> +#include <QtCore/QString> +#include <QtNetwork/QNetworkReply> +#include <QDeclarativeListProperty> + +#include <qgeopositioninfo.h> + +//! [0] +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(); +//! [0] +private: + QString m_dayOfWeek; + QString m_weather; + QString m_weatherDesc; + QString m_tempString; +//! [1] +}; +//! [1] + +Q_DECLARE_METATYPE(WeatherData); + +class AppModelPrivate; +//! [2] +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(QDeclarativeListProperty<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; + QDeclarativeListProperty<WeatherData> forecast() const; + +public slots: + Q_INVOKABLE void refreshWeather(); + +//! [2] +private slots: + void networkSessionOpened(); + void positionUpdated(QGeoPositionInfo gpsPos); + // these would have QNetworkReply* params but for the signalmapper + void handleGeoNetworkData(QObject *networkReply); + void handleWeatherNetworkData(QObject *networkReply); + +//! [3] +signals: + void readyChanged(); + void useGpsChanged(); + void cityChanged(); + void weatherChanged(); + +//! [3] + +private: + AppModelPrivate *d; + +//! [4] +}; +//! [4] + +#endif // APPMODEL_H diff --git a/examples/weatherinfo/components/BigForecastIcon.qml b/examples/weatherinfo/components/BigForecastIcon.qml new file mode 100644 index 00000000..f4afa0f0 --- /dev/null +++ b/examples/weatherinfo/components/BigForecastIcon.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: current + + property string topText: "20*" + property string bottomText: "Mostly cloudy" + property string weather: "showers" + property real smallSide: (current.width < current.height ? current.width : current.height) + + Text { + text: current.topText + font.pointSize: 28 + anchors { + top: current.top + left: current.left + topMargin: 5 + leftMargin: 5 + } + } + + WeatherIcon { + weather: current.weather + anchors.centerIn: parent + width: current.smallSide + height: current.smallSide + } + + Text { + text: current.bottomText + font.pointSize: 28 + anchors { + bottom: current.bottom + right: current.right + bottomMargin: 20 + rightMargin: 5 + } + } +} diff --git a/examples/weatherinfo/components/ForecastIcon.qml b/examples/weatherinfo/components/ForecastIcon.qml new file mode 100644 index 00000000..00165ca9 --- /dev/null +++ b/examples/weatherinfo/components/ForecastIcon.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: top + + property string topText: "Mon" + property string weather: "showers" + property string bottomText: "22*/23*" + + Text { + id: dayText + horizontalAlignment: Text.AlignHCenter + width: top.width + text: top.topText + + anchors.top: parent.top + anchors.topMargin: top.height / 5 - dayText.paintedHeight + anchors.horizontalCenter: parent.horizontalCenter + } + + WeatherIcon { + id: icon + weather: top.weather + + property real side: { + var h = 3 * top.height / 5 + if (top.width < h) + top.width; + else + h; + } + + width: icon.side + height: icon.side + + anchors.centerIn: parent + } + + Text { + id: tempText + horizontalAlignment: Text.AlignHCenter + width: top.width + text: top.bottomText + + anchors.bottom: parent.bottom + anchors.bottomMargin: top.height / 5 - tempText.paintedHeight + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/weatherinfo/components/WeatherIcon.qml b/examples/weatherinfo/components/WeatherIcon.qml new file mode 100644 index 00000000..190660c8 --- /dev/null +++ b/examples/weatherinfo/components/WeatherIcon.qml @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: container + + property string weather: "sunny" + + Image { + id: img + source: "../icons/weather-" + container.weather + ".png" + smooth: true + anchors.fill: parent + } +} diff --git a/examples/weatherinfo/icons/README.txt b/examples/weatherinfo/icons/README.txt new file mode 100644 index 00000000..d3841532 --- /dev/null +++ b/examples/weatherinfo/icons/README.txt @@ -0,0 +1,5 @@ +The scalable icons are from: + +http://tango.freedesktop.org/Tango_Icon_Library +http://darkobra.deviantart.com/art/Tango-Weather-Icon-Pack-98024429 + diff --git a/examples/weatherinfo/icons/weather-few-clouds.png b/examples/weatherinfo/icons/weather-few-clouds.png Binary files differnew file mode 100644 index 00000000..a8000ef0 --- /dev/null +++ b/examples/weatherinfo/icons/weather-few-clouds.png diff --git a/examples/weatherinfo/icons/weather-fog.png b/examples/weatherinfo/icons/weather-fog.png Binary files differnew file mode 100644 index 00000000..9ffe9c4a --- /dev/null +++ b/examples/weatherinfo/icons/weather-fog.png diff --git a/examples/weatherinfo/icons/weather-haze.png b/examples/weatherinfo/icons/weather-haze.png Binary files differnew file mode 100644 index 00000000..ae6f13eb --- /dev/null +++ b/examples/weatherinfo/icons/weather-haze.png diff --git a/examples/weatherinfo/icons/weather-icy.png b/examples/weatherinfo/icons/weather-icy.png Binary files differnew file mode 100644 index 00000000..18d20384 --- /dev/null +++ b/examples/weatherinfo/icons/weather-icy.png diff --git a/examples/weatherinfo/icons/weather-overcast.png b/examples/weatherinfo/icons/weather-overcast.png Binary files differnew file mode 100644 index 00000000..9d50f77f --- /dev/null +++ b/examples/weatherinfo/icons/weather-overcast.png diff --git a/examples/weatherinfo/icons/weather-showers.png b/examples/weatherinfo/icons/weather-showers.png Binary files differnew file mode 100644 index 00000000..07489aaa --- /dev/null +++ b/examples/weatherinfo/icons/weather-showers.png diff --git a/examples/weatherinfo/icons/weather-sleet.png b/examples/weatherinfo/icons/weather-sleet.png Binary files differnew file mode 100644 index 00000000..3d225895 --- /dev/null +++ b/examples/weatherinfo/icons/weather-sleet.png diff --git a/examples/weatherinfo/icons/weather-snow.png b/examples/weatherinfo/icons/weather-snow.png Binary files differnew file mode 100644 index 00000000..e7426e3c --- /dev/null +++ b/examples/weatherinfo/icons/weather-snow.png diff --git a/examples/weatherinfo/icons/weather-storm.png b/examples/weatherinfo/icons/weather-storm.png Binary files differnew file mode 100644 index 00000000..6b6b366a --- /dev/null +++ b/examples/weatherinfo/icons/weather-storm.png diff --git a/examples/weatherinfo/icons/weather-sunny-very-few-clouds.png b/examples/weatherinfo/icons/weather-sunny-very-few-clouds.png Binary files differnew file mode 100644 index 00000000..133bcb29 --- /dev/null +++ b/examples/weatherinfo/icons/weather-sunny-very-few-clouds.png diff --git a/examples/weatherinfo/icons/weather-sunny.png b/examples/weatherinfo/icons/weather-sunny.png Binary files differnew file mode 100644 index 00000000..0fac921d --- /dev/null +++ b/examples/weatherinfo/icons/weather-sunny.png diff --git a/examples/weatherinfo/icons/weather-thundershower.png b/examples/weatherinfo/icons/weather-thundershower.png Binary files differnew file mode 100644 index 00000000..1aff1639 --- /dev/null +++ b/examples/weatherinfo/icons/weather-thundershower.png diff --git a/examples/weatherinfo/main.cpp b/examples/weatherinfo/main.cpp new file mode 100644 index 00000000..82209157 --- /dev/null +++ b/examples/weatherinfo/main.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include <QtDeclarative/QQuickView> +#include <QtDeclarative/QDeclarativeEngine> +#include <QtDeclarative/QDeclarativeContext> +#include <QtDeclarative/QQuickItem> + +//! [0] +#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"); + +//! [0] + qRegisterMetaType<WeatherData>("WeatherData"); +//! [1] + 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(); +} +//! [1] diff --git a/examples/weatherinfo/weatherinfo.pro b/examples/weatherinfo/weatherinfo.pro new file mode 100644 index 00000000..e87bea21 --- /dev/null +++ b/examples/weatherinfo/weatherinfo.pro @@ -0,0 +1,30 @@ +TEMPLATE = app +TARGET = weatherinfo + +QT += core \ + network \ + location \ + declarative \ + quick + +symbian:TARGET.CAPABILITY += Location \ + NetworkServices \ + ReadUserData + +SOURCES += main.cpp \ + appmodel.cpp + +OTHER_FILES += weatherinfo.qml \ + components/WeatherIcon.qml \ + components/ForecastIcon.qml \ + components/BigForecastIcon.qml + +RESOURCES += weatherinfo.qrc + +HEADERS += appmodel.h + +#install +target.path = $$[QT_INSTALL_EXAMPLES]/qtlocation/weatherinfo +sources.files = $$SOURCES $HEADERS $$RESOURCES $$FORMS *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtlocation/weatherinfo +INSTALLS += target sources diff --git a/examples/weatherinfo/weatherinfo.qml b/examples/weatherinfo/weatherinfo.qml new file mode 100644 index 00000000..f3c521a5 --- /dev/null +++ b/examples/weatherinfo/weatherinfo.qml @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "components" +//! [0] +import WeatherInfo 1.0 + +Item { + id: window +//! [0] + width: 360 + height: 640 + + state: "loading" + + states: [ + State { + name: "loading" + PropertyChanges { target: main; opacity: 0 } + PropertyChanges { target: wait; opacity: 1 } + }, + State { + name: "ready" + PropertyChanges { target: main; opacity: 1 } + PropertyChanges { target: wait; opacity: 0 } + } + ] +//! [1] + AppModel { + id: model + onReadyChanged: { + if (model.ready) + window.state = "ready" + else + window.state = "loading" + } + } +//! [1] + Item { + id: wait + anchors.fill: parent + + Text { + text: "Loading weather data..." + anchors.centerIn: parent + font.pointSize: 18 + } + } + + Item { + id: main + anchors.fill: parent + + Column { + spacing: 6 + + anchors { + fill: parent + topMargin: 6; bottomMargin: 6; leftMargin: 6; rightMargin: 6 + } + + Rectangle { + width: parent.width + height: 25 + color: "lightgrey" + + Text { + text: (model.hasValidCity ? model.city : "Unknown location") + (model.useGps ? " (GPS)" : "") + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (model.useGps) { + model.useGps = false + model.city = "Brisbane" + } else { + switch (model.city) { + case "Brisbane": + model.city = "Oslo" + break + case "Oslo": + model.city = "Helsinki" + break + case "Helsinki": + model.city = "New York" + break + case "New York": + model.useGps = true + break + } + } + } + } + } + +//! [3] + BigForecastIcon { + id: current + + width: main.width - 3 + height: 2 * (main.height - 25 - 12) / 3 + + weather: (model.hasValidWeather + ? model.weather.weather + : "sunny") +//! [3] + topText: (model.hasValidWeather + ? model.weather.tempString + : "??") + bottomText: (model.hasValidWeather + ? model.weather.weatherDesc + : "No weather data") + + MouseArea { + anchors.fill: parent + onClicked: { + model.refreshWeather() + } + } +//! [4] + } +//! [4] + + Row { + id: iconRow + spacing: 6 + + width: main.width - 3 + height: (main.height - 25 - 24) / 3 + + property real iconWidth: iconRow.width / 4 - 10 + property real iconHeight: iconRow.height + + ForecastIcon { + id: forecast1 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[0].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[0].tempString : "??/??") + weather: (model.hasValidWeather ? + model.forecast[0].weather : "showers") + } + ForecastIcon { + id: forecast2 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[1].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[1].tempString : "??/??") + weather: (model.hasValidWeather ? + model.forecast[1].weather : "showers") + } + ForecastIcon { + id: forecast3 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[2].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[2].tempString : "??/??") + weather: (model.hasValidWeather ? + model.forecast[2].weather : "showers") + } + ForecastIcon { + id: forecast4 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[3].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[3].tempString : "??/??") + weather: (model.hasValidWeather ? + model.forecast[3].weather : "showers") + } + + } + } + } +//! [2] +} +//! [2] diff --git a/examples/weatherinfo/weatherinfo.qrc b/examples/weatherinfo/weatherinfo.qrc new file mode 100644 index 00000000..7b79dbea --- /dev/null +++ b/examples/weatherinfo/weatherinfo.qrc @@ -0,0 +1,20 @@ +<RCC> + <qresource prefix="/"> + <file>weatherinfo.qml</file> + <file>components/BigForecastIcon.qml</file> + <file>components/ForecastIcon.qml</file> + <file>components/WeatherIcon.qml</file> + <file>icons/weather-few-clouds.png</file> + <file>icons/weather-fog.png</file> + <file>icons/weather-haze.png</file> + <file>icons/weather-icy.png</file> + <file>icons/weather-overcast.png</file> + <file>icons/weather-showers.png</file> + <file>icons/weather-sleet.png</file> + <file>icons/weather-snow.png</file> + <file>icons/weather-storm.png</file> + <file>icons/weather-sunny-very-few-clouds.png</file> + <file>icons/weather-sunny.png</file> + <file>icons/weather-thundershower.png</file> + </qresource> +</RCC> |