├── .gitignore
├── README.md
├── demonstrate
└── demonstrate.gif
├── image
├── autumn.png
├── cloudy_moon.png
├── cloudy_sun.png
├── fine_moon.png
├── fine_sun.png
├── rain_moon.png
├── rain_sun.png
├── snow_moon.png
├── snow_sun.png
├── spring.png
├── summer.png
├── thundershower.png
└── winter.png
├── qml.qrc
├── src
├── main.cpp
├── main.qml
├── myjsonparse.cpp
├── myjsonparse.h
├── mymodel.cpp
├── mymodel.h
├── weatherdata.cpp
└── weatherdata.h
└── weather.pro
/.gitignore:
--------------------------------------------------------------------------------
1 | debug/
2 | release/
3 | *.user
4 | *.Debug
5 | *.Release
6 | Makefile
7 | *.stash
8 | *.rc
9 | *.exe
10 | *.qmlc
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/README.md
--------------------------------------------------------------------------------
/demonstrate/demonstrate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/demonstrate/demonstrate.gif
--------------------------------------------------------------------------------
/image/autumn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/autumn.png
--------------------------------------------------------------------------------
/image/cloudy_moon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/cloudy_moon.png
--------------------------------------------------------------------------------
/image/cloudy_sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/cloudy_sun.png
--------------------------------------------------------------------------------
/image/fine_moon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/fine_moon.png
--------------------------------------------------------------------------------
/image/fine_sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/fine_sun.png
--------------------------------------------------------------------------------
/image/rain_moon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/rain_moon.png
--------------------------------------------------------------------------------
/image/rain_sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/rain_sun.png
--------------------------------------------------------------------------------
/image/snow_moon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/snow_moon.png
--------------------------------------------------------------------------------
/image/snow_sun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/snow_sun.png
--------------------------------------------------------------------------------
/image/spring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/spring.png
--------------------------------------------------------------------------------
/image/summer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/summer.png
--------------------------------------------------------------------------------
/image/thundershower.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/thundershower.png
--------------------------------------------------------------------------------
/image/winter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengps/Weather/eff48ab07102707702101314339d1cb391f750c5/image/winter.png
--------------------------------------------------------------------------------
/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | image/spring.png
4 | image/summer.png
5 | image/winter.png
6 | image/fine_moon.png
7 | image/fine_sun.png
8 | image/rain_moon.png
9 | image/rain_sun.png
10 | image/snow_moon.png
11 | image/snow_sun.png
12 | image/thundershower.png
13 | image/cloudy_moon.png
14 | image/cloudy_sun.png
15 | image/autumn.png
16 | src/main.qml
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "mymodel.h"
2 | #include "weatherdata.h"
3 | #include
4 | #include
5 | #include
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
10 | QApplication app(argc, argv);
11 |
12 | qmlRegisterType("an.weather", 1, 0, "IndexData");
13 | qmlRegisterType("an.weather", 1, 0, "WeatherData");
14 | qmlRegisterType("an.model", 1, 0, "MyModel");
15 |
16 | QQmlApplicationEngine engine;
17 | MyModel *myModel = new MyModel();
18 | engine.rootContext()->setContextProperty("myModel", myModel);
19 | engine.load(QUrl(QLatin1String("qrc:/src/main.qml")));
20 | if (engine.rootObjects().isEmpty())
21 | return -1;
22 |
23 | return app.exec();
24 | }
25 |
--------------------------------------------------------------------------------
/src/main.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.7
2 | import QtQuick.Controls 2.2
3 | import QtQuick.Window 2.3
4 | import QtCharts 2.2
5 | import an.weather 1.0
6 | import an.model 1.0
7 |
8 | ApplicationWindow
9 | {
10 | id: root
11 |
12 | width: mobile ? Screen.desktopAvailableWidth : 400
13 | height: mobile ? Screen.desktopAvailableHeight : 600
14 | color: "#CDEDEC"
15 | visible: true
16 |
17 | property bool mobile: Qt.platform.os == "android";
18 |
19 | Connections
20 | {
21 | target: myModel
22 | onReadyChanged:
23 | {
24 | if (myModel.ready)
25 | {
26 | refreshAnimation.restart();
27 | maxSeries.clear();
28 | minSeries.clear();
29 | for (var i = 0; i < 4; i++)
30 | {
31 | maxSeries.append(i + 1, myModel.weatherData[i].maxTemperature);
32 | minSeries.append(i + 1, myModel.weatherData[i].minTemperature);
33 | }
34 | }
35 | }
36 | }
37 |
38 | NumberAnimation
39 | {
40 | id: refreshAnimation
41 | target: page
42 | property: "y"
43 | duration: 200
44 | from: page.pullHeight
45 | to: 0
46 | easing.type: Easing.Linear
47 | }
48 |
49 | Image
50 | {
51 | id: season //季节背景
52 | anchors.fill: parent
53 | fillMode: Image.PreserveAspectFit
54 | mipmap: true
55 | antialiasing: true
56 | opacity: 0.4
57 | source: getSeason()
58 |
59 | function getSeason()
60 | {
61 | var time = new Date();
62 | var season = time.getMonth() / 3;
63 |
64 | if (season <= 1)
65 | return "qrc:image/spring.png";
66 | else if (season > 1 && season <= 2)
67 | return "qrc:image/summer.png";
68 | else if (season > 2 && season <= 3)
69 | return "qrc:image/autumn.png";
70 | else return "qrc:image/winter.png";
71 | }
72 | }
73 |
74 | Component
75 | {
76 | id: delegate
77 |
78 | Item
79 | {
80 | width: 70
81 | height: 220
82 |
83 | Text
84 | {
85 | id: dateText
86 | width: 70
87 | height: 20
88 | font.family: "方正"
89 | font.pointSize: 10
90 | horizontalAlignment: Text.AlignHCenter
91 | verticalAlignment: Text.AlignVCenter
92 | text: index != 0 ? date : "今日"
93 | }
94 |
95 | Text
96 | {
97 | id: weatherText
98 | width: 70
99 | height: 20
100 | font.family: "方正"
101 | font.pointSize: 10
102 | anchors.top: dateText.bottom
103 | anchors.topMargin: 5
104 | horizontalAlignment: Text.AlignHCenter
105 | verticalAlignment: Text.AlignVCenter
106 | text: myModel.ready ? weather : "未知"
107 | }
108 |
109 | Image
110 | {
111 | id: day
112 | anchors.top: weatherText.bottom
113 | anchors.topMargin: 2
114 | width: 70
115 | height: 50
116 | mipmap: true
117 | fillMode: Image.PreserveAspectFit
118 | source: myModel.ready ? dayPicture : ""
119 | }
120 |
121 | Text
122 | {
123 | id: temperatureText
124 | width: 70
125 | height: 20
126 | font.family: "方正"
127 | font.pointSize: 10
128 | anchors.top: day.bottom
129 | anchors.topMargin: 5
130 | horizontalAlignment: Text.AlignHCenter
131 | verticalAlignment: Text.AlignVCenter
132 | text: myModel.ready ? myModel.weatherData[index].minTemperature + " ~ " +
133 | myModel.weatherData[index].maxTemperature + "℃" : "未知"
134 | }
135 |
136 | Image
137 | {
138 | id: night
139 | anchors.top: temperatureText.bottom
140 | anchors.topMargin: 5
141 | width: 70
142 | height: 50
143 | mipmap: true
144 | fillMode: Image.PreserveAspectFit
145 | source: myModel.ready ? nightPicture : ""
146 | }
147 |
148 | Text
149 | {
150 | id: windText
151 | width: 70
152 | height: 20
153 | font.family: "方正"
154 | font.pointSize: 10
155 | anchors.top: night.bottom
156 | anchors.topMargin: 5
157 | horizontalAlignment: Text.AlignHCenter
158 | verticalAlignment: Text.AlignVCenter
159 | text: myModel.ready ? wind : "未知"
160 | }
161 | }
162 | }
163 |
164 | Flickable
165 | {
166 | id: page
167 | width: parent.width
168 | height: parent.height
169 | contentWidth: content.width
170 | contentHeight: content.height
171 |
172 | property int pullHeight: 64
173 |
174 | states: [
175 | State {
176 | id: downRefreshState
177 | name: "downRefresh"
178 | when: page.contentY < -page.pullHeight
179 | StateChangeScript
180 | {
181 | script:
182 | {
183 | print("下拉刷新")
184 | page.y = page.pullHeight
185 | myModel.downRefresh();
186 | }
187 | }
188 | }
189 | ]
190 |
191 | Item
192 | {
193 | id: content
194 | width: root.width
195 | height: tipsRect.y + tipsRect.height + 50
196 |
197 | Text
198 | {
199 | id: city
200 | anchors.horizontalCenter: parent.horizontalCenter
201 | anchors.top: parent.top
202 | anchors.topMargin: 5
203 | font.pointSize: 18
204 | font.family: "方正"
205 | text: "城市:" + (myModel.ready ? myModel.city : "载入中...")
206 | }
207 |
208 | Text
209 | {
210 | id: updateMsg
211 | anchors.horizontalCenter: city.horizontalCenter
212 | anchors.top: city.bottom
213 | anchors.topMargin: 5
214 | font.pointSize: 8
215 | font.family: "方正"
216 | color: "gray"
217 | text: myModel.ready ? "天气数据已经更新" : "天气数据更新中...."
218 | }
219 |
220 | Text
221 | {
222 | id: temperature
223 | anchors.horizontalCenter: updateMsg.horizontalCenter
224 | anchors.top: updateMsg.bottom
225 | anchors.topMargin: 70
226 | font.pointSize: 14
227 | font.family: "方正"
228 | text: "今日温度:" + (myModel.ready ? myModel.weatherData[0].minTemperature
229 | + " ~ " + myModel.weatherData[0].maxTemperature + "℃": "载入中...")
230 | }
231 |
232 | Text
233 | {
234 | id: pm25
235 | anchors.horizontalCenter: temperature.horizontalCenter
236 | anchors.top: temperature.bottom
237 | anchors.topMargin: 10
238 | font.pointSize: 14
239 | font.family: "方正"
240 | text: "空气污染(PM2.5):" + (myModel.ready ? myModel.pm25 + calcPollutionLevel(myModel.pm25) : "载入中...")
241 | function calcPollutionLevel(arg)
242 | {
243 | var intArg = parseInt(arg);
244 | if (intArg >= 0 && intArg < 35)
245 | return "(优秀)";
246 | else if (intArg >= 35 && intArg < 75)
247 | return "(良好)";
248 | else if (intArg >= 75 && intArg < 115)
249 | return "(轻度污染)";
250 | else if (intArg >= 115 && intArg < 150)
251 | return "(中度污染)";
252 | else if (intArg >= 150 && intArg < 250)
253 | return "(重度污染)";
254 | else return "(严重污染)";
255 | }
256 | }
257 |
258 | Text
259 | {
260 | id: time
261 | anchors.horizontalCenter: pm25.horizontalCenter
262 | anchors.top: pm25.bottom
263 | anchors.topMargin: 10
264 | font.pointSize: 14
265 | font.family: "方正"
266 | color: "red"
267 | text: myModel.ready ? myModel.weatherData[0].date : "载入中..."
268 | }
269 |
270 | Row
271 | {
272 | id: day_night
273 | anchors.horizontalCenter: parent.horizontalCenter
274 | anchors.top: time.bottom
275 | anchors.topMargin: 10
276 | spacing: 15
277 |
278 | Image
279 | {
280 | width: 100
281 | height: 50
282 | mipmap: true
283 | fillMode: Image.PreserveAspectFit
284 | source: myModel.ready ? myModel.weatherData[0].dayPicture : ""
285 | }
286 |
287 | Image
288 | {
289 | width: 100
290 | height: 50
291 | mipmap: true
292 | fillMode: Image.PreserveAspectFit
293 | source: myModel.ready ? myModel.weatherData[0].nightPicture : ""
294 | }
295 | }
296 |
297 | Row
298 | {
299 | id: day_night_text
300 | anchors.top: day_night.bottom
301 | anchors.topMargin: 2
302 | anchors.horizontalCenter: day_night.horizontalCenter
303 |
304 | Text
305 | {
306 | width: 120
307 | height: 20
308 | font.pointSize: 11
309 | font.family: "方正"
310 | horizontalAlignment: Text.AlignHCenter
311 | verticalAlignment: Text.AlignVCenter
312 | text: qsTr("白天")
313 | }
314 |
315 | Text
316 | {
317 | width: 120
318 | height: 20
319 | font.pointSize: 11
320 | font.family: "方正"
321 | horizontalAlignment: Text.AlignHCenter
322 | verticalAlignment: Text.AlignVCenter
323 | text: qsTr("夜晚")
324 | }
325 | }
326 |
327 | ListView
328 | {
329 | id: futureWeather
330 | width: contentWidth
331 | orientation: ListView.Horizontal
332 | anchors.top: day_night_text.bottom
333 | anchors.topMargin: 50
334 | anchors.horizontalCenter: day_night_text.horizontalCenter
335 | spacing: 20
336 | model: myModel.weatherData
337 | delegate: delegate
338 | }
339 |
340 | ChartView
341 | {
342 | id: futureChart
343 | width: parent.width
344 | height: 200
345 | legend.font.family: "方正"
346 | legend.font.pointSize: 10
347 | y: futureWeather.y + 190
348 | anchors.horizontalCenter: futureWeather.horizontalCenter
349 | antialiasing: true
350 | backgroundColor: "transparent"
351 | plotAreaColor: "transparent"
352 | Component.onCompleted:
353 | {
354 | futureChart.axisX().visible = false;
355 | futureChart.axisY().visible = false;
356 | }
357 |
358 | ValueAxis
359 | {
360 | id: axisX
361 | min: 0.5
362 | max: 4.5
363 | }
364 |
365 | ValueAxis
366 | {
367 | id: axisY
368 | min: -5
369 | max: 40
370 | }
371 |
372 | LineSeries
373 | {
374 | id: maxSeries
375 | name: "最高温"
376 | pointLabelsFont.family: "方正"
377 | pointLabelsFont.pointSize: 10
378 | pointLabelsVisible: true
379 | pointLabelsFormat: "@yPoint °" //更改label的格式
380 | color: "red"
381 | width: 2
382 | axisX: axisX
383 | axisY: axisY
384 | }
385 |
386 | LineSeries
387 | {
388 | id: minSeries
389 | name: "最低温"
390 | pointLabelsFont.family: "方正"
391 | pointLabelsFont.pointSize: 10
392 | pointLabelsVisible: true
393 | pointLabelsFormat: "@yPoint °"
394 | color: "#8080FF"
395 | width: 2
396 | axisX: axisX
397 | axisY: axisY
398 | }
399 | }
400 |
401 | Rectangle
402 | {
403 | id: tipsRect
404 | width: parent.width - 40
405 | height: 280
406 | radius: 5
407 | clip: true
408 | anchors.top: futureChart.bottom
409 | anchors.topMargin: 10
410 | anchors.horizontalCenter: futureWeather.horizontalCenter
411 | color: "#335C8D89"
412 |
413 | Text
414 | {
415 | id: tipsText
416 | text: "小提示:"
417 | anchors.left: tipsRect.left
418 | anchors.leftMargin: 15
419 | anchors.top: tipsRect.top
420 | anchors.topMargin: 15
421 | font.pointSize: 13
422 | font.bold: true
423 | font.family: "方正"
424 | horizontalAlignment: Text.AlignHCenter
425 | verticalAlignment: Text.AlignVCenter
426 | color: "#FC993C"
427 | }
428 |
429 | Flickable //之所以使用一个Flickable,是因为下面的ListView的滑动失效了,具体原因不明
430 | {
431 | anchors.left: tipsRect.left
432 | anchors.leftMargin: 10
433 | anchors.right: tipsRect.right
434 | anchors.rightMargin: 10
435 | anchors.top: tipsText.bottom
436 | anchors.topMargin: 10
437 | width: parent.width
438 | height: parent.height
439 | contentWidth: tipsView.contentWidth
440 | contentHeight: tipsView.contentHeight
441 |
442 | ListView
443 | {
444 | id: tipsView
445 | height: parent.width
446 | width: parent.width
447 | orientation: ListView.Horizontal
448 | model: myModel.indexData
449 | spacing: 20
450 | delegate: Component
451 | {
452 | Column
453 | {
454 | spacing: 20
455 |
456 | Text
457 | {
458 | id: title
459 | width: 80
460 | text: modelData.title
461 | horizontalAlignment: Text.AlignHCenter
462 | verticalAlignment: Text.AlignVCenter
463 | font.pointSize: 11
464 | font.family: "方正"
465 | }
466 |
467 | Text
468 | {
469 | id: tipt
470 | width: 80
471 | text: modelData.tipt
472 | horizontalAlignment: Text.AlignHCenter
473 | verticalAlignment: Text.AlignVCenter
474 | font.pointSize: 11
475 | font.family: "方正"
476 | }
477 |
478 | Text
479 | {
480 | id: state
481 | width: 80
482 | text: modelData.state
483 | horizontalAlignment: Text.AlignHCenter
484 | verticalAlignment: Text.AlignVCenter
485 | font.pointSize: 11
486 | font.family: "方正"
487 | }
488 |
489 | Text
490 | {
491 | id: descript
492 | width: 80
493 | text: modelData.descript
494 | wrapMode: Text.Wrap
495 | horizontalAlignment: Text.AlignHCenter
496 | verticalAlignment: Text.AlignVCenter
497 | font.pointSize: 11
498 | font.family: "方正"
499 | }
500 | }
501 | }
502 | }
503 | }
504 | }
505 | }
506 | }
507 | }
508 |
--------------------------------------------------------------------------------
/src/myjsonparse.cpp:
--------------------------------------------------------------------------------
1 | #include "myjsonparse.h"
2 | #include "weatherdata.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | MyJsonParse::MyJsonParse()
9 | : m_success(false)
10 | {
11 |
12 | }
13 |
14 | MyJsonParse::MyJsonParse(const QJsonDocument &doc)
15 | : m_success(false),
16 | m_jsonDoc(doc)
17 | {
18 |
19 | }
20 |
21 | MyJsonParse::~MyJsonParse()
22 | {
23 |
24 | }
25 |
26 | void MyJsonParse::setJsonDocument(const QJsonDocument &doc)
27 | {
28 | if (!doc.isNull())
29 | m_jsonDoc = doc;
30 | if (m_jsonDoc.isObject())
31 | {
32 | QJsonObject object = m_jsonDoc.object();
33 | //用于判断api返回的数据是否可用
34 | m_success = object.value("status").toString() == "success";
35 | }
36 | }
37 |
38 | QJsonDocument MyJsonParse::jsonDocument() const
39 | {
40 | return m_jsonDoc;
41 | }
42 |
43 | QString MyJsonParse::getCurrentCity() const
44 | {
45 | if (m_success)
46 | {
47 | QJsonObject object = m_jsonDoc.object();
48 | QJsonArray result = object.value("results").toArray();
49 | object = result[0].toObject();
50 | return object.value("currentCity").toString();
51 | }
52 | return "获取城市失败";
53 | }
54 |
55 | QString MyJsonParse::getPm25() const
56 | {
57 | if (m_success)
58 | {
59 | QJsonObject object = m_jsonDoc.object();
60 | QJsonArray result = object.value("results").toArray();
61 | object = result[0].toObject();
62 | return object.value("pm25").toString();
63 | }
64 | return "获取PM25失败";
65 | }
66 |
67 | QList MyJsonParse::getIndexList() const
68 | {
69 | QList indexs;
70 | if (m_success)
71 | {
72 | QJsonObject object = m_jsonDoc.object();
73 | QJsonArray array = object.value("results").toArray();
74 | object = array[0].toObject();
75 | array = object.value("index").toArray();
76 | for (auto it : array)
77 | {
78 | object = it.toObject();
79 | IndexData *indexData = new IndexData;
80 | indexData->setDescript(object.value("des").toString());
81 | indexData->setTipt(object.value("tipt").toString());
82 | indexData->setTitle(object.value("title").toString());
83 | indexData->setState(object.value("zs").toString());
84 | indexs.push_back(indexData);
85 | }
86 | }
87 | return indexs;
88 | }
89 |
90 | QList MyJsonParse::getWeatherList() const
91 | {
92 | QList weathers;
93 | if (m_success)
94 | {
95 | QJsonObject object = m_jsonDoc.object();
96 | QJsonArray array = object.value("results").toArray();
97 | object = array[0].toObject();
98 | array = object.value("weather_data").toArray();
99 | for (auto it : array)
100 | {
101 | object = it.toObject();
102 | WeatherData *weatherData = new WeatherData;
103 | weatherData->setDate(object.value("date").toString());
104 | //温度的格式为 max ~ min℃;
105 | QString temperature = object.value("temperature").toString();
106 | QStringList temperatures = temperature.left(temperature.length() - 1).split(" ~ ");
107 | weatherData->setMaxTemperature(temperatures.at(0).toInt());
108 | weatherData->setMinTemperature(temperatures.at(1).toInt());
109 | QString weather = object.value("weather").toString();
110 | weatherData->setWeather(weather);
111 | QString imagestr;
112 | if (weather.left(1) == "晴") //晴或晴转xx
113 | imagestr = "fine";
114 | else if ((weather.left(2) == "多云" ) || weather.left(1) == "阴") //多云或多云转xx 阴或阴转xx
115 | imagestr = "cloudy";
116 | else if (weather.contains("雨"))
117 | imagestr = "rain";
118 | else if (weather.contains("雪"))
119 | imagestr = "snow";
120 | else imagestr = "fine";
121 | weatherData->setDayPicture("qrc:/image/" + imagestr + "_sun.png");
122 | weatherData->setNightPicture("qrc:/image/" + imagestr + "_moon.png");
123 | weatherData->setWind(object.value("wind").toString());
124 | weathers.push_back(weatherData);
125 | }
126 | }
127 |
128 | return weathers;
129 | }
130 |
--------------------------------------------------------------------------------
/src/myjsonparse.h:
--------------------------------------------------------------------------------
1 | #ifndef MYJSONPARSE_H
2 | #define MYJSONPARSE_H
3 | #include
4 | #include
5 |
6 | class IndexData;
7 | class WeatherData;
8 | class MyJsonParse
9 | {
10 | public :
11 | MyJsonParse();
12 | MyJsonParse(const QJsonDocument &doc);
13 | ~MyJsonParse();
14 |
15 | void setJsonDocument(const QJsonDocument &doc);
16 | QJsonDocument jsonDocument() const;
17 |
18 | public:
19 | QString getCurrentCity() const;
20 | QString getPm25() const;
21 | QList getIndexList() const;
22 | QList getWeatherList() const;
23 |
24 | private:
25 | bool m_success;
26 | QJsonDocument m_jsonDoc;
27 | };
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/src/mymodel.cpp:
--------------------------------------------------------------------------------
1 | #include "mymodel.h"
2 | #include "weatherdata.h"
3 | #include
4 |
5 | class MyModelPrivate
6 | {
7 | public:
8 | MyModelPrivate() { }
9 | ~MyModelPrivate() { cleanup(); }
10 |
11 | void cleanup()
12 | {
13 | if (!m_index.isEmpty())
14 | {
15 | for (auto it : m_index)
16 | delete it;
17 | m_index.clear();
18 | }
19 |
20 | if (!m_data.isEmpty())
21 | {
22 | for (auto it : m_data)
23 | delete it;
24 | m_data.clear();
25 | }
26 | }
27 |
28 | public:
29 | QString m_city;
30 | QString m_pm25;
31 | QList m_index;
32 | QList m_data;
33 | };
34 |
35 | MyModel::MyModel(QObject *parent)
36 | : QObject(parent),
37 | m_netManager(new QNetworkAccessManager(this)),
38 | m_ready(false),
39 | m_dptr(new MyModelPrivate),
40 | m_api("http://api.map.baidu.com/telematics/v3/weather"
41 | "?location=武汉&output=json&ak=YGtqUyHOKe5xtaDzi2pmMZVEMdDNlG8F")
42 | {
43 | readSettings();
44 | m_geoPosSrc = QGeoPositionInfoSource::createDefaultSource(this);
45 | connect(m_geoPosSrc, &QGeoPositionInfoSource::positionUpdated, this, &MyModel::updatePosition);
46 | connect(m_netManager, &QNetworkAccessManager::finished, this, &MyModel::updateWeather);
47 | m_timerID = startTimer(1000 * 60 * 5); //五分钟更新一次天气
48 | m_geoPosSrc->startUpdates();
49 | //如果位置获取失败,则使用默认位置
50 | if (m_geoPosSrc->error() != QGeoPositionInfoSource::NoError)
51 | m_netManager->get(QNetworkRequest(QUrl(m_api)));
52 | }
53 |
54 | MyModel::~MyModel()
55 | {
56 | delete m_dptr;
57 | if (m_timerID != 0)
58 | killTimer(m_timerID);
59 | }
60 |
61 | void MyModel::readSettings()
62 | {
63 | QSettings setting("Settings//local.ini", QSettings::IniFormat);
64 | QString api = setting.value("api").toString();
65 | if (!api.isEmpty())
66 | m_api = api;
67 | }
68 |
69 | void MyModel::writeSettings()
70 | {
71 | QSettings setting("Settings//local.ini", QSettings::IniFormat);
72 | setting.setValue("api", m_api);
73 | }
74 |
75 | void MyModel::downRefresh()
76 | {
77 | setReady(false);
78 | m_netManager->get(QNetworkRequest(QUrl(m_api)));
79 | }
80 |
81 | void MyModel::updatePosition(QGeoPositionInfo gpsPos)
82 | {
83 | if (gpsPos.isValid())
84 | {
85 | //获取经纬度
86 | QString pos = QString("%1,%2").arg(gpsPos.coordinate().longitude()).arg(gpsPos.coordinate().latitude());
87 | m_api = QString("http://api.map.baidu.com/telematics/v3/weather"
88 | "?location=%1&output=json&ak=YGtqUyHOKe5xtaDzi2pmMZVEMdDNlG8F").arg(pos);
89 | m_netManager->get(QNetworkRequest(QUrl(m_api)));
90 | writeSettings();
91 | }
92 | }
93 |
94 | void MyModel::updateWeather(QNetworkReply *reply)
95 | {
96 | QString str = reply->readAll();
97 | QJsonParseError error;
98 | QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &error);
99 | if (!doc.isNull() && (error.error == QJsonParseError::NoError))
100 | {
101 | m_parse.setJsonDocument(doc);
102 | setPm25(m_parse.getPm25());
103 | setCity(m_parse.getCurrentCity());
104 | m_dptr->m_index = m_parse.getIndexList();
105 | m_dptr->m_data = m_parse.getWeatherList();
106 | setReady(true);
107 | emit indexDataChanged();
108 | emit weatherDataChanged();
109 | }
110 | }
111 |
112 | void MyModel::timerEvent(QTimerEvent *event)
113 | {
114 | Q_UNUSED(event)
115 | downRefresh();
116 | }
117 |
118 | QQmlListProperty MyModel::indexData()
119 | {
120 | return QQmlListProperty(this, m_dptr->m_index);
121 | }
122 |
123 | QQmlListProperty MyModel::weatherData()
124 | {
125 | return QQmlListProperty(this, m_dptr->m_data);
126 | }
127 |
128 | QString MyModel::city() const
129 | {
130 | return m_dptr->m_city;
131 | }
132 |
133 | bool MyModel::ready() const
134 | {
135 | return m_ready;
136 | }
137 |
138 | void MyModel::setReady(bool arg)
139 | {
140 | if (arg != m_ready)
141 | {
142 | m_ready = arg;
143 | emit readyChanged();
144 | }
145 | }
146 |
147 | QString MyModel::pm25() const
148 | {
149 | return m_dptr->m_pm25;
150 | }
151 |
152 | void MyModel::setCity(const QString &arg)
153 | {
154 | if (arg != m_dptr->m_city)
155 | {
156 | m_dptr->m_city = arg;
157 | emit cityChanged();
158 | }
159 | }
160 |
161 | void MyModel::setPm25(const QString &arg)
162 | {
163 | if (arg != m_dptr->m_pm25)
164 | {
165 | m_dptr->m_pm25 = arg;
166 | emit pm25Changed();
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/mymodel.h:
--------------------------------------------------------------------------------
1 | #ifndef MYMODEL_H
2 | #define MYMODEL_H
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include "myjsonparse.h"
10 |
11 | class MyModelPrivate;
12 | class MyModel : public QObject
13 | {
14 | Q_OBJECT
15 |
16 | Q_PROPERTY(QQmlListProperty indexData READ indexData NOTIFY indexDataChanged)
17 | Q_PROPERTY(QQmlListProperty weatherData READ weatherData NOTIFY weatherDataChanged)
18 | Q_PROPERTY(QString city READ city WRITE setCity NOTIFY cityChanged)
19 | Q_PROPERTY(QString pm25 READ pm25 WRITE setPm25 NOTIFY pm25Changed)
20 | Q_PROPERTY(bool ready READ ready WRITE setReady NOTIFY readyChanged)
21 |
22 | public:
23 | MyModel(QObject *parent = nullptr);
24 | ~MyModel();
25 |
26 | QQmlListProperty indexData();
27 | QQmlListProperty weatherData();
28 |
29 | QString city() const;
30 | QString pm25() const;
31 | bool ready() const;
32 | void readSettings();
33 | void writeSettings();
34 |
35 | public slots:
36 | void downRefresh(); //下拉刷新
37 | void setReady(bool arg);
38 | void setCity(const QString &arg);
39 | void setPm25(const QString &arg);
40 | void updatePosition(QGeoPositionInfo gpsPos);
41 | void updateWeather(QNetworkReply *reply);
42 |
43 | protected:
44 | void timerEvent(QTimerEvent *event);
45 |
46 | signals:
47 | void indexDataChanged();
48 | void weatherDataChanged();
49 | void readyChanged();
50 | void cityChanged();
51 | void pm25Changed();
52 |
53 | private:
54 | MyModelPrivate *m_dptr;
55 | QGeoPositionInfoSource *m_geoPosSrc;
56 | QNetworkAccessManager *m_netManager;
57 | MyJsonParse m_parse;
58 | QString m_api;
59 | bool m_ready;
60 | int m_timerID;
61 | };
62 |
63 | #endif // MYMODEL_H
64 |
--------------------------------------------------------------------------------
/src/weatherdata.cpp:
--------------------------------------------------------------------------------
1 | #include "weatherdata.h"
2 |
3 | IndexData::IndexData(QObject *parent)
4 | : QObject(parent),
5 | m_descript("未知"),
6 | m_tipt("未知"),
7 | m_title("未知"),
8 | m_state("未知")
9 | {
10 |
11 | }
12 |
13 | IndexData::~IndexData()
14 | {
15 |
16 | }
17 |
18 | QString IndexData::descript() const
19 | {
20 | return m_descript;
21 | }
22 |
23 | QString IndexData::tipt() const
24 | {
25 | return m_tipt;
26 | }
27 |
28 | QString IndexData::title() const
29 | {
30 | return m_title;
31 | }
32 |
33 | QString IndexData::state() const
34 | {
35 | return m_state;
36 | }
37 |
38 | void IndexData::setDescript(const QString &arg)
39 | {
40 | if (arg != m_descript)
41 | {
42 | m_descript = arg;
43 | emit descriptChanged();
44 | }
45 | }
46 |
47 | void IndexData::setTipt(const QString &arg)
48 | {
49 | if (arg != m_tipt)
50 | {
51 | m_tipt = arg;
52 | emit tiptChanged();
53 | }
54 | }
55 |
56 | void IndexData::setTitle(const QString &arg)
57 | {
58 | if (arg != m_title)
59 | {
60 | m_title = arg;
61 | emit titleChanged();
62 | }
63 | }
64 |
65 | void IndexData::setState(const QString &arg)
66 | {
67 | if (arg != m_state)
68 | {
69 | m_state = arg;
70 | emit stateChanged();
71 | }
72 | }
73 |
74 |
75 | WeatherData::WeatherData(QObject *parent)
76 | : QObject(parent),
77 | m_date("未知"),
78 | m_dayPicture(""),
79 | m_nightPicture(""),
80 | m_weather("未知"),
81 | m_wind("未知"),
82 | m_maxTemperature(0),
83 | m_minTemperature(0)
84 | {
85 |
86 | }
87 |
88 | WeatherData::~WeatherData()
89 | {
90 |
91 | }
92 |
93 | QString WeatherData::date() const
94 | {
95 | return m_date;
96 | }
97 |
98 | QString WeatherData::dayPicture() const
99 | {
100 | return m_dayPicture;
101 | }
102 |
103 | QString WeatherData::nightPicture() const
104 | {
105 | return m_nightPicture;
106 | }
107 |
108 | QString WeatherData::weather() const
109 | {
110 | return m_weather;
111 | }
112 |
113 | QString WeatherData::wind() const
114 | {
115 | return m_wind;
116 | }
117 |
118 | int WeatherData::maxTemperature() const
119 | {
120 | return m_maxTemperature;
121 | }
122 |
123 | int WeatherData::minTemperature() const
124 | {
125 | return m_minTemperature;
126 | }
127 |
128 | void WeatherData::setDate(const QString &arg)
129 | {
130 | if (arg != m_date)
131 | {
132 | m_date = arg;
133 | emit dateChanged();
134 | }
135 | }
136 |
137 | void WeatherData::setDayPicture(const QString &arg)
138 | {
139 | if (arg != m_dayPicture)
140 | {
141 | m_dayPicture = arg;
142 | emit dayPictureChanged();
143 | }
144 | }
145 |
146 | void WeatherData::setNightPicture(const QString &arg)
147 | {
148 | if (arg != m_nightPicture)
149 | {
150 | m_nightPicture = arg;
151 | emit nightPictureChanged();
152 | }
153 | }
154 |
155 | void WeatherData::setWeather(const QString &arg)
156 | {
157 | if (arg != m_weather)
158 | {
159 | m_weather = arg;
160 | emit weatherChanged();
161 | }
162 | }
163 |
164 | void WeatherData::setWind(const QString &arg)
165 | {
166 | if (arg != m_wind)
167 | {
168 | m_wind = arg;
169 | emit windChanged();
170 | }
171 | }
172 |
173 | void WeatherData::setMaxTemperature(int arg)
174 | {
175 | if (arg != m_maxTemperature)
176 | {
177 | m_maxTemperature = arg;
178 | emit maxTemperatureChanged();
179 | }
180 | }
181 |
182 | void WeatherData::setMinTemperature(int arg)
183 | {
184 | if (arg != m_minTemperature)
185 | {
186 | m_minTemperature = arg;
187 | emit minTemperatureChanged();
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/weatherdata.h:
--------------------------------------------------------------------------------
1 | #ifndef WEATHERDATA_H
2 | #define WEATHERDATA_H
3 | #include
4 |
5 | class IndexData : public QObject
6 | {
7 | Q_OBJECT
8 |
9 | Q_PROPERTY(QString descript READ descript WRITE setDescript NOTIFY descriptChanged)
10 | Q_PROPERTY(QString tipt READ tipt WRITE setTipt NOTIFY tiptChanged)
11 | Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
12 | Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged)
13 |
14 | public:
15 | IndexData(QObject *parent = nullptr);
16 | ~IndexData();
17 |
18 | QString descript() const;
19 | QString tipt() const;
20 | QString title() const;
21 | QString state() const;
22 |
23 | public slots:
24 | void setDescript(const QString &arg);
25 | void setTipt(const QString &arg);
26 | void setTitle(const QString &arg);
27 | void setState(const QString &arg);
28 |
29 | signals:
30 | void descriptChanged();
31 | void tiptChanged();
32 | void titleChanged();
33 | void stateChanged();
34 |
35 | private:
36 | QString m_descript;
37 | QString m_tipt;
38 | QString m_title;
39 | QString m_state;
40 | };
41 |
42 | class WeatherData : public QObject
43 | {
44 | Q_OBJECT
45 |
46 | Q_PROPERTY(QString date READ date WRITE setDate NOTIFY dateChanged)
47 | Q_PROPERTY(QString dayPicture READ dayPicture WRITE setDayPicture NOTIFY dayPictureChanged)
48 | Q_PROPERTY(QString nightPicture READ nightPicture WRITE setNightPicture NOTIFY nightPictureChanged)
49 | Q_PROPERTY(QString weather READ weather WRITE setWeather NOTIFY weatherChanged)
50 | Q_PROPERTY(QString wind READ wind WRITE setWind NOTIFY windChanged)
51 | Q_PROPERTY(int maxTemperature READ maxTemperature WRITE setMaxTemperature NOTIFY maxTemperatureChanged)
52 | Q_PROPERTY(int minTemperature READ minTemperature WRITE setMinTemperature NOTIFY minTemperatureChanged)
53 |
54 | public:
55 | WeatherData(QObject *parent = nullptr);
56 | ~WeatherData();
57 |
58 | QString date() const;
59 | QString dayPicture() const;
60 | QString nightPicture() const;
61 | QString weather() const;
62 | QString wind() const;
63 | int maxTemperature() const;
64 | int minTemperature() const;
65 |
66 | public slots:
67 | void setDate(const QString &arg);
68 | void setDayPicture(const QString &arg);
69 | void setNightPicture(const QString &arg);
70 | void setWeather(const QString &arg);
71 | void setWind(const QString &arg);
72 | void setMaxTemperature(int arg);
73 | void setMinTemperature(int arg);
74 |
75 | signals:
76 | void dateChanged();
77 | void dayPictureChanged();
78 | void nightPictureChanged();
79 | void weatherChanged();
80 | void windChanged();
81 | void maxTemperatureChanged();
82 | void minTemperatureChanged();
83 |
84 | private:
85 | QString m_date;
86 | QString m_dayPicture;
87 | QString m_nightPicture;
88 | QString m_weather;
89 | QString m_wind;
90 | int m_maxTemperature;
91 | int m_minTemperature;
92 | };
93 |
94 | #endif // WEATHERDATA_H
95 |
--------------------------------------------------------------------------------
/weather.pro:
--------------------------------------------------------------------------------
1 | QT += core qml network positioning widgets
2 |
3 | CONFIG += c++11
4 |
5 | TARGET = Weather
6 |
7 | TEMPLATE = app
8 |
9 | SOURCES += src/main.cpp \
10 | src/myjsonparse.cpp \
11 | src/mymodel.cpp \
12 | src/weatherdata.cpp
13 |
14 | # The following define makes your compiler emit warnings if you use
15 | # any feature of Qt which as been marked deprecated (the exact warnings
16 | # depend on your compiler). Please consult the documentation of the
17 | # deprecated API in order to know how to port your code away from it.
18 | DEFINES += QT_DEPRECATED_WARNINGS
19 |
20 | # You can also make your code fail to compile if you use deprecated APIs.
21 | # In order to do so, uncomment the following line.
22 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
23 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
24 |
25 | HEADERS += src/myjsonparse.h \
26 | src/mymodel.h \
27 | src/weatherdata.h
28 |
29 | RESOURCES += qml.qrc
30 |
--------------------------------------------------------------------------------