目录
1.界面预览
2.窗口的设置
设置无状态栏
setWindowFlag(Qt::FramelessWindowHint);
设置左键弹窗关闭
menuQuit = new QMenu(this);
QAction *closeAct = new QAction(QIcon(":/res/close.png"), tr("退出"), this);
menuQuit->addAction(closeAct);
connect(menuQuit,&QMenu::triggered,this,[=]{
this->close();
});
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::RightButton){
//qDebug() << "right Mouse clicked!";
menuQuit->exec(QCursor::pos());
}
}
设置窗口移动
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::RightButton){
实现的逻辑
7.5 天气预报数据接口
第一种:
数据返回:
//qDebug() << "right Mouse clicked!";
menuQuit->exec(QCursor::pos());
}
//鼠标当前位置 event->globalPos();,
//窗口当前位置 this->pos()窗口新位置event->globalPos() - mOffset
if(event->button() == Qt::LeftButton){
// qDebug() << event->globalPos() << this->pos();
mOffset = event->globalPos()-this->pos();
}
}
//鼠标左键按下后的移动,导致这个事件被调用,设置窗口的新位置
void Widget::mouseMoveEvent(QMouseEvent *event)
{
this->move(event->globalPos() - mOffset);
}
3.网络通信的架构
在计算机网络和软件开发中, CS 架构( Client-Server Architecture ,客户端 - 服务器架构)和 BS 架构 (Browser-Server Architecture ,浏览器 - 服务器架构)是两种主要的应用程序架构。
3.1CS架构(客户端-服务端架构)
CS 架构是一种典型的两层结构,包括客户端和服务器两个部分。在这种架构中,客户端和服务器通过网络进行通信,每部分都有明确的职责。
- 用户界面通常在客户端呈现。
- 可以是桌面应用程序、移动应用或专用软件。
- 负责向服务器发送请求,接收和处理服务器响应。
服务端
- 管理数据和业务逻辑。
- 处理来自客户端的请求,并发送回响应。
- 通常承载在远程系统上,如数据库服务器、应用服务器等。
特点
- 需要为每种操作系统或平台单独开发客户端。
- 高效的数据处理和响应能力。
- 在客户端设备上占用资源(如内存和处理能力)。
3.2BS架构(浏览器-服务端架构)
BS架构是一种基于Web的三层或多层架构,主要通过Web浏览器作为客户端访问服务器上的应用程序。
浏览器(客户端)
- 使用标准Web浏览器(如Chrome、Firefox等)作为客户端。
- 无需安装额外的软件,使用HTML、CSS和JavaScript显示内容。
服务端
- 和CS架构中的服务器类似,处理业务逻辑和数据存储。
- 通过Web服务(如HTTP服务器)提供页面和数据。
特点
- 跨平台兼容性强,可以在任何支持Web浏览器的设备上运行。
- 客户端无需安装专用软件,容易维护和更新。
- 可能依赖网络性能,因为所有操作都在服务器上进行。
3.3CS与BS的区别
- 部署和维护:BS架构易于部署和维护,而CS架构通常需要在每个客户端单独安装和更新。
- 性能:CS架构可以更有效地利用客户端的计算资源,适合高性能要求的应用。BS架构依赖于服务器 的性能和网络延迟。
- 安全性:CS架构中,数据经常在客户端和服务器之间传输,可能需要更复杂的安全措施。BS架构 中,敏感数据主要存储在服务器端。
3.4HTTP概述
HTTP(Hypertext Transfer Protocol)是一种用于传输超文本(如HTML)数据的应用层协议,用于在客户端和服务器之间传输信息。以下是HTTP的基本概念:
请求和响应
- HTTP遵循客户端-服务器模型,其中客户端发送HTTP请求,服务器响应该请求并返回所需的数据。
请求方法
- HTTP定义了不同的请求方法,最常见的是GET(获取资源)、POST(提交数据)、PUT(更新资源)、DELETE(删除资源)等
状态码
- HTTP响应包含一个状态码,用于表示请求的处理结果。常见的状态码包括200(成功)、404(未找到)、500(服务器内部错误)等
URL(统一资源定位符)
- URL用于标识互联网上的资源位置。HTTP请求中包含URL,指示客户端请求的资源。
安全性
- HTTP本身是不安全的,数据以明文形式传输。为了增加安全性,通常会使用HTTPS(HTTP Secure),通过加密和认证机制保护数据的传输。
Cookie和Session
- HTTP使用Cookie来跟踪用户会话状态,服务器可以通过在响应中设置Cookie来在客户端存储信息。Session则是在服务器端存储用户会话信息的一种机制。
缓存
- HTTP支持缓存机制,允许客户端和代理服务器缓存响应,以减少数据传输和提高性能。
3.5HTTP编程
Qt 中的 HTTP 编程主要涉及使用 Qt 的网络模块来进行 HTTP 请求和处理 HTTP 响应。 Qt 提供了一系列类来处 理网络通信,其中最常用的类是 QNetworkAccessManager , QNetworkRequest 、 QNetworkReply 以 及相关的支持类。
第一步包含必要的头文件
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
第二步实例化QNetworkAccessManager
对象,用于发送HTTP请求并处理响应。
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
第三步使用QNetworkRequest
对象创建HTTP请求,设置URL、请求方法、请求头等信息
QNetworkRequest request(QUrl("http://example.com/api"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
第四步使用QNetworkAccessManager
发送HTTP请求,并获取返回的QNetworkReply
对象。
QNetworkReply *reply = manager->get(request);
第五步连接QNetworkReply
的信号来处理HTTP响应,包括读取响应数据、处理错误等。
connect(reply, &QNetworkReply::finished, this, [reply]() {
if (reply->error() == QNetworkReply::NoError) {
QByteArray responseData = reply->readAll();
// 处理响应数据
} else {
// 处理错误
}
reply->deleteLater();
});
第六步释放资源
delete manager;
例子:
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QDebug>
int main(int argc, char *argv[])
{
// 创建Qt应用程序对象
QCoreApplication a(argc, argv);
// 创建网络访问管理器对象
QNetworkAccessManager manager;
// 创建HTTP请求对象,指定请求的URL
QNetworkRequest request(QUrl("http://example.com"));
// 发送HTTP GET请求
QNetworkReply *reply = manager.get(request);
// 处理HTTP响应
QObject::connect(reply, &QNetworkReply::finished, [&]() {
// 检查是否有错误发生
if (reply->error()) {
qDebug() << "Error:" << reply->errorString();
return;
}
// 读取响应数据
QString response = reply->readAll();
qDebug() << "Response:" << response;
// 释放reply对象
reply->deleteLater();
});
// 运行Qt应用程序事件循环
return a.exec();
}
4.JSON
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它易于人阅读和编写,同时也易于 机器解析和生成。JSON是基于JavaScript的一个子集,尽管它是独立于语言的,且有多种语言支持。 JSON常用于网络应用程序中的数据传输,尤其是在Web应用程序中与后端服务器通信。
原因 | 描述 |
易于阅读和编写
|
JSON
的结构简单、清晰,对人类来说易于阅读和编写。
|
轻量级数据格式
|
相较于
XML
等标记语言,
JSON
更轻量,使用更少的符号,数据体积更小。
|
易于解析和生成
|
大多数编程语言都提供了解析和生成
JSON
的内置支持或库。
|
跨语言支持
|
JSON
是独立于语言的,被广泛支持和使用在多种编程语言中。
|
网络友好
|
JSON
格式适合
Web
环境,易于通过网络传输,是
Web API
的常用格式。
|
数据互操作性
|
作为一种标准化格式,
JSON
提高了不同系统间的数据互操作性
|
4.1QT生成JSON数据
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QDebug>
// 创建一个JSON文件并写入数据
void createJsonFile() {
// 创建一个JSON对象,包含键值对
QJsonObject jsonObj;
jsonObj["name"] = "John Doe";
jsonObj["age"] = 30;
jsonObj["email"] = "john.doe@example.com";
// 创建一个JSON数组
QJsonArray jsonArr;
jsonArr.append("C++");
jsonArr.append("Python");
jsonArr.append("JavaScript");
jsonArr.append(123);
// 将数组添加到JSON对象
jsonObj["languages"] = jsonArr;
// 将JSON对象转换为JSON文档
QJsonDocument jsonDoc(jsonObj);
// 将JSON文档转换为字符串(可以选择压缩格式)
QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);
// 将JSON数据写入文件
QFile file("output.json");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open file for writing";
return;
}
file.write(jsonData);
file.close();
qDebug() << "JSON data saved to output.json";
}
int main()
{
// 调用创建JSON文件的函数
createJsonFile();
return 0;
}
解释说明:
- 创建JSON对象:使用 QJsonObject 来构建JSON对象,并使用键值对填充数据。
- 创建JSON数组:使用 QJsonArray 来创建一个数组,并添加元素。
- 组合JSON结构:将JSON数组添加到JSON对象中。
- 生成JSON文档:通过 QJsonDocument 来处理JSON数据,可以选择格式化(缩进)或压缩形式。
- 保存到文件:创建 QFile 对象,打开文件,写入JSON数据,并关闭文件。
这个例子展示了Qt处理JSON的基础流程,包括创建、填充数据、转换为字符串,以及写入文件。
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建一个JSON对象并添加键值对
QJsonObject rootObj;
rootObj["cityid"] = "1010100";
rootObj["date"] = "2024-01-23";
rootObj["weather"] = "雨夹雪";
rootObj["tmp"] = 3;
// 创建一个JSON数组并添加元素
QJsonArray jsonArray;
jsonArray.append("data1");
jsonArray.append("data2");
jsonArray.append("data3");
jsonArray.append(100);
// 将数组添加到JSON对象
rootObj["testArry"] = jsonArray;
// 将JSON对象转换为JSON文档
QJsonDocument jsonDoc(rootObj);
// 将JSON文档转换为字节数组
QByteArray jsonArry = jsonDoc.toJson();
// 创建一个文件对象并写入JSON数据
QFile file("D:/QT/test.json");
if (!file.open(QIODevice::WriteOnly)) {
// 打开文件失败,输出错误信息
qDebug() << "Failed to open file for writing";
return;
}
file.write(jsonArry);
file.close();
// 输出操作完成的消息
qDebug() << "JSON data saved to D:/QT/test.json";
}
Widget::~Widget()
{
delete ui;
}
4.2QT解析JSON数据
在 Qt 中解析 JSON 数据通常涉及到使用 QJsonDocument 、 QJsonObject 和 QJsonArray 类。这些类提供 了处理JSON 数据的必要工具,使您能够从 JSON 字符串中提取信息、遍历 JSON 对象或数组,并访问具体 的数据项。以下是一个基本的示例,展示了如何在Qt 中解析 JSON 字符串。
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
void parseJson() {
// JSON字符串
/*
R 是用于定义原始字符串字面量(Raw String Literal)的标记。
在C++中,原始字符串字面量是一种方便的语法,
用于创建包含多行文本和特殊字符的字符串,而无需转义。
R"("chenlichen")"
*/
QString testStr = "chenli\"c";
QString jsonString = R"(
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"skills": ["C++", "Python", "JavaScript"]
}
)";
// 将JSON字符串转换为QJsonDocument
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
// 检查JSON文档是否包含一个对象
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
// 获取JSON对象
QJsonObject jsonObj = jsonDoc.object();
// 访问对象的键值
QString name = jsonObj["name"].toString();
int age = jsonObj["age"].toInt();
QString email = jsonObj["email"].toString();
qDebug() << "Name:" << name;
qDebug() << "Age:" << age;
qDebug() << "Email:" << email;
// 处理JSON数组
if (jsonObj.contains("skills") && jsonObj["skills"].isArray()) {
QJsonArray skillsArray = jsonObj["skills"].toArray();
for (const QJsonValue &value : skillsArray) {
qDebug() << "Skill:" << value.toString();
}
}
} else {
qDebug() << "Invalid JSON...";
}
}
int main()
{
parseJson();
return 0;
}
解释说明:
- 字符串转换为 QJsonDocument :使用 QJsonDocument::fromJson 方法将JSON字符串转换为
- QJsonDocument 对象。
- 提取 QJsonObject :如果 QJsonDocument 包含一个JSON对象,使用 object() 方法获取它。
- 访问对象数据:使用键(如 "name" 、 "age" )访问 QJsonObject 中的数据。
- 处理数组:如果对象包含一个数组,使用 QJsonArray 来遍历数组中的元素。
4.3将JSON数据解析到QMap中
#include <QJsonDocument>
#include <QJsonObject>
#include <QMap>
#include <QDebug>
void parseJsonToMap() {
// JSON字符串
QString jsonString = R"(
{
"name": "John Doe",
"age": "30",
"email": "john.doe@example.com"
}
)";
// 将JSON字符串转换为QJsonDocument
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
// 准备一个QMap来存储解析的数据
QMap<QString, QString> dataMap;
// 解析JSON对象并填充QMap
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
QJsonObject jsonObj = jsonDoc.object();
for (auto key : jsonObj.keys()) {
dataMap[key] = jsonObj.value(key).toString();
}
} else {
qDebug() << "Invalid JSON...";
}
// 打印QMap内容
for (auto key : dataMap.keys()) {
qDebug() << key << ":" << dataMap[key];
}
}
int main()
{
parseJsonToMap();
return 0;
}
解释说明:
- 从JSON字符串创建 QJsonDocument :使用 QJsonDocument::fromJson 来解析JSON字符串。
- 创建 QMap :定义一个 QMap<QString, QString> 来存储键值对。
- 遍历JSON对象:使用 keys() 方法获取所有键,然后遍历这些键,将对应的值添加到 QMap 中。
- 打印 QMap 内容:遍历 QMap 并打印键值对。
5.完整程序
5.1.1widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMenu>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QList>
#include <QLabel>
#include "cityname.h"
#include "day.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public:
QList<QLabel *> _WeekList;
QList<QLabel *> _DateList;
QList<QLabel *> _IconList;
QList<QLabel *> _WeathList;
QList<QLabel *> _AirqList;
QList<QLabel *> _FLList;
QList<QLabel *> _FXList;
protected:
//检测鼠标点击事件
void mousePressEvent(QMouseEvent *event) override;
//检测鼠标点击窗口移动事件
void mouseMoveEvent(QMouseEvent *event) override;
//
bool eventFilter(QObject *watched, QEvent *event) override;
private slots:
//读取天气的数据
void readHttpRply(QNetworkReply *reply);
//搜索城市
void on_pushButton_clicked();
void on_lineEditsearch_returnPressed();
private:
Ui::Widget *ui;
QMenu *menuQuit;//退出界面
QPoint moveDistance; //界面移动
QNetworkAccessManager *manager;//网络请求
CityName citynames;//城市名称
QMap <QString, QString> mTypeMap;//天气图片
day days[7];//7日天气数据
//解析天气的Json数据
void parseCurrentWeatherJsonData(QByteArray readWeatherBuf);
//解析7日天气的Json数据
void parseCurrentWeatherJsonDatanew(QByteArray readWeatherBuf);
//数据更新
void updataUI();
//画高温曲线
void drawTempLineHigh();
//画低温曲线
void drawTempLineLow();
};
#endif // WIDGET_H
5.1.2widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QMouseEvent>
#include <QDebug>
#include <QIcon>
#include <QAction>
#include <QNetworkAccessManager>
#include <QMessageBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
menuQuit = new QMenu(this);
_WeekList << ui->labelday01 << ui->labelday02
<< ui->labelday03 << ui->labelday04
<< ui->labelday05 << ui->labelday06;
_DateList << ui->labeldaydata01 << ui->labeldaydata02
<< ui->labeldaydata03 << ui->labeldaydata04
<< ui->labeldaydata05 << ui->labeldaydata06;
_IconList << ui->labelweath01 << ui->labelweath02
<< ui->labelweath03 << ui->labelweath04
<< ui->labelweath05 << ui->labelweath06;
_WeathList << ui->labelweathdata01 << ui->labelweathdata02
<< ui->labelweathdata03 << ui->labelweathdata04
<< ui->labelweathdata05 << ui->labelweathdata06;
_AirqList << ui->labelairq01 << ui->labelairq02
<< ui->labelairq03 << ui->labelairq04
<< ui->labelairq05 << ui->labelairq06;
_FXList << ui->labelwind01 << ui->labelwind02
<< ui->labelwind03 << ui->labelwind04
<< ui->labelwind05 << ui->labelwind06;
_FLList << ui->labelwinddata01 << ui->labelwinddata02
<<ui->labelwinddata03 <<ui->labelwinddata04
<<ui->labelwinddata05 <<ui->labelwinddata06;
setFixedSize(378,682);//锁定显示的大小
setWindowFlag(Qt::FramelessWindowHint);//去除边框
menuQuit->setStyleSheet("QMenu::item {color:red}");//设置单项菜单文字颜色
//用户点击菜单后执行回调函数程序结束
connect(menuQuit, &QMenu::triggered, this, [=](){//此信号在触发此菜单中的操作时发出。
this->close();
});
manager = new QNetworkAccessManager(this);
//QString url = "http://v1.yiketianqi.com/api?unescape=1&version=v61&appid=17212311&appsecret=wgJCYY4x";
//QString url = "http://t.weather.itboy.net";
QString url = "http://v1.yiketianqi.com/api?unescape=1&version=v9&appid=17212311&appsecret=wgJCYY4x";
manager->get(QNetworkRequest(QUrl(url)));//发起get请求
connect(manager, &QNetworkAccessManager::finished, this, &Widget::readHttpRply);//访问成功后执行回调函数读取天气的数据
mTypeMap.insert("暴雪",":/pic/type/BaoXue.png");
mTypeMap.insert("暴雨",":/pic/type/BaoYu. png");
mTypeMap.insert("暴雨到大暴雨",":/pic/type/BaoYuDaoDaBaoYu.png");
mTypeMap.insert("大暴雨",":/pic/type/DaBaoYu.png");
mTypeMap.insert("大暴雨到特大暴雨",":/pic/type/DaBaoYuDaoTeDaBaoYu.png");
mTypeMap.insert("大到暴雪",":/pic/type/DaDaoBaoXue.png");
mTypeMap.insert("大雪",":/pic/type/DaXue.png");
mTypeMap.insert("大雨",":/pic/type/DaYu.png");
mTypeMap.insert("冻雨",":/pic/type/DongYu.png");
mTypeMap.insert("多云",":/pic/type/DuoYun.png");
mTypeMap.insert("浮沉",":/pic/type/FuChen.png");
mTypeMap.insert("雷阵雨",":/pic/type/LeiZhenYu.png");
mTypeMap.insert("雷阵雨伴有冰雹",":/pic/type/LeiZhenYuBanYouBingBao.png");
mTypeMap.insert("霾",":/pic/type/Mai.png");
mTypeMap.insert("强沙尘暴",":/pic/type/QiangShaChenBao.png");
mTypeMap.insert("晴",":/pic/type/Qing.png");
mTypeMap.insert("沙尘暴",":/pic/type/ShaChenBao.png");
mTypeMap.insert("特大暴雨",":/pic/type/TeDaBaoYu.png");
mTypeMap.insert("undefined",":/pic/type/undefined.png");
mTypeMap.insert("雾",":/pic/type/Wu.png");
mTypeMap.insert("小到中雪",":/pic/type/XiaoDaoZhongXue.png");
mTypeMap.insert("小到中雨",":/pic/type/XiaoDaoZhongYu.png");
mTypeMap.insert("小雪",":/pic/type/XiaoXue.png");
mTypeMap.insert("小雨",":/pic/type/XiaoYu.png");
mTypeMap.insert("雪",":/pic/type/Xue.png");
mTypeMap.insert("扬沙",":/pic/type/YangSha.png");
mTypeMap.insert("阴",":/pic/type/Yin.png");
mTypeMap.insert("雨",":/pic/type/Yu.png");
mTypeMap.insert("雨夹雪",":/pic/type/YuJiaXue.png");
mTypeMap.insert("阵雪",":/pic/type/ZhenXue.png");
mTypeMap.insert("阵雨",":/pic/type/ZhenYu.png");
mTypeMap.insert("中到大雪",":/pic/type/ZhongDaoDaXue.png");
mTypeMap.insert("中到大雨",":/pic/type/ZhongDaoDaYu.png");
mTypeMap.insert("中雪",":/pic/type/ZhongXue.png");
mTypeMap.insert("中雨",":/pic/type/ZhongYu.png");
ui->widget0404->installEventFilter(this);
ui->widget0405->installEventFilter(this);
}
Widget::~Widget()
{
delete ui;
}
//检测鼠标点击事件 窗口的关闭和移动
void Widget::mousePressEvent(QMouseEvent *event)
{
//为菜单添加一个动作
QAction *closeAct = new QAction(QIcon(":/pic/close.png"), tr("退出"), this);
//鼠标右键按下
if(event->button() == Qt::RightButton){
menuQuit->clear();
menuQuit->addAction(closeAct);//将获取的图片添加到menu中
menuQuit->exec(QCursor::pos());//QCursor::pos()
}
//鼠标左键按下
if(event->button() == Qt::LeftButton){
moveDistance = event->globalPos() - this->pos();//鼠标相对于窗口的偏移值
}
}
//检测鼠标点击窗口移动事件
void Widget::mouseMoveEvent(QMouseEvent *event)
{
//event->globalPos() - moveDistance 新窗口位置的坐标
this->move(event->globalPos() - moveDistance);//移动到新窗口位置
}
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(watched == ui->widget0404 && event->type() == QEvent::Paint){
drawTempLineHigh();
}
if(watched == ui->widget0405 && event->type() == QEvent::Paint){
drawTempLineLow();
}
}
//解析天气的Json数据
void Widget::parseCurrentWeatherJsonData(QByteArray readWeatherBuf)
{
//把QByteArray转成JSONDoc
QJsonDocument jsonDoc = QJsonDocument::fromJson(readWeatherBuf);
if(!jsonDoc.isNull() && jsonDoc.isObject()){
QJsonObject jsonRoot = jsonDoc.object();//把JsonDoc转成JsonObj
//解析日期和时间
ui->labelweek->setText(jsonRoot["date"].toString() + " " + jsonRoot["week"].toString());
//解析城市
ui->labelcurrentcity->setText(jsonRoot["city"].toString());
//当前的温度
ui->labelcurrenttemp->setText(jsonRoot["tem"].toString() + "℃");
//温度的区间
ui->labeltemp->setText(jsonRoot["tem2"].toString() + "~" + jsonRoot["tem1"].toString());
//天气情况
ui->labelweathtype->setText(jsonRoot["wea"].toString());
//天气情况图片
ui->labelpic->setPixmap(mTypeMap[jsonRoot["wea"].toString()]);
//感冒系数
ui->labelganmao->setText("感冒系数:" + jsonRoot["air_tips"].toString());
//风的方向
ui->labelwindtext->setText(jsonRoot["win"].toString());
//风速
ui->labelwinddata->setText(jsonRoot["win_speed"].toString());
//pm2.5
ui->labelPM25data->setText(jsonRoot["air_pm25"].toString());
//湿度
ui->labelshidudata->setText(jsonRoot["humidity"].toString());
//空气质量
ui->labelairdata->setText(jsonRoot["air_level"].toString());
}
}
void Widget::parseCurrentWeatherJsonDatanew(QByteArray readWeatherBuf)
{
QJsonDocument jsonDoc = QJsonDocument::fromJson(readWeatherBuf);//将原始数据QByteArray转换成QJsonDocument
//QJsonDocument不为空并且是QJsonObject
if(!jsonDoc.isNull() && jsonDoc.isObject()){
QJsonObject jsonRoot = jsonDoc.object();//将原始数据QJsonDocument转换成QJsonObject
days[0]._City = jsonRoot["city"].toString();
days[0]._Pm25 = jsonRoot["aqi"].toObject()["pm25"].toString();
if(jsonRoot.contains("data") && jsonRoot["data"].isArray()){
QJsonArray weaArray = jsonRoot["data"].toArray();
for(int i = 0; i < weaArray.size(); i++){
QJsonObject obj = weaArray[i].toObject();
days[i]._Date = obj["date"].toString();//保存一周天气的各种数据
days[i]._Week = obj["week"].toString();
days[i]._WeathType = obj["wea"].toString();
days[i]._Temp = obj["tem"].toString();
days[i]._TempLow = obj["tem2"].toString();
days[i]._TempHigh = obj["tem1"].toString();
days[i]._FX = obj["win"].toArray()[0].toString();
days[i]._FL = obj["win_speed"].toString();
days[i]._Airq = obj["air_level"].toString();
days[i]._Tips = obj["index"].toArray()[0].toObject()["desc"].toString();
days[i]._Hu = obj["humidity"].toString();
}
}
}
updataUI();
}
void Widget::updataUI()
{
QPixmap pixMap;
//解析日期
ui->labelweek->setText(days[0]._Date + " " + days[0]._Week);
//解析城市
ui->labelcurrentcity->setText(days[0]._City);
//当前的温度
ui->labelcurrenttemp->setText(days[0]._Temp + "℃");
qDebug() << days[0]._Temp;
//温度的区间
ui->labeltemp->setText("温度区间:" + days[0]._TempLow + "~" + days[0]._TempHigh);
//天气情况
ui->labelweathtype->setText(days[0]._WeathType);
//天气情况图片
ui->labelpic->setPixmap(mTypeMap[days[0]._WeathType]);
//感冒系数
ui->labelganmao->setText("紫外线指数:" + days[0]._Tips);
//风的方向
ui->labelwindtext->setText(days[0]._FX);
//风速
ui->labelwinddata->setText(days[0]._FL);
//pm2.5
ui->labelPM25data->setText(days[0]._Pm25);
//湿度
ui->labelshidudata->setText(days[0]._Hu);
//空气质量
ui->labelairdata->setText(days[0]._Airq);
for(int i = 0; i < 6; i++){
_WeekList [i]->setText(days[i]._Week);//星期的显示
_WeekList [0]->setText("今天");
_WeekList [1]->setText("明天");
_WeekList [2]->setText("后天");//week的显示
QStringList dateList = days[i]._Date.split("-");
_DateList [i]->setText(dateList.at(1) + "-" + dateList.at(2));//日期的显示
int inxdex = days[i]._WeathType.indexOf("转");//查找 "转" 的位置
if(inxdex != -1){
pixMap = mTypeMap[days[i]._WeathType.left(inxdex)];//截取左边的天气
}else{
pixMap = mTypeMap[days[i]._WeathType];
}
pixMap = pixMap.scaled(_IconList[i]->size(), Qt::KeepAspectRatio, Qt::FastTransformation);//图片的缩放
_IconList [i]->setPixmap(pixMap);//天气图片的显示
_WeathList[i]->setText(days[i]._WeathType);//天气的显示
QString airq = days[i]._Airq;
_AirqList [i]->setText(airq);//空气质量的显示
if(airq == "优"){
_AirqList[i]->setStyleSheet("background-color: rgb(188, 255, 1);border-radius: 7px;");//改变背景色
}
if(airq == "良"){
_AirqList[i]->setStyleSheet("background-color: rgb(255, 228, 19);border-radius: 7px;");//改变背景色
}
if(airq == "轻度"){
_AirqList[i]->setStyleSheet("background-color: rgb(255, 55, 39);border-radius: 7px;");//改变背景色
}
if(airq == "中度"){
_AirqList[i]->setStyleSheet("background-color: rgb(189, 41, 29);border-radius: 7px;");//改变背景色
}
if(airq == "重度"){
_AirqList[i]->setStyleSheet("background-color: rgb(110, 24, 17);border-radius: 7px;");//改变背景色
}
_FXList[i]->setText(days[i]._FX);
inxdex = days[i]._FL.indexOf("转");//查找 "转" 的位置
QString fl;
if(inxdex != -1){
fl = days[i]._FL.left(inxdex);//截取左边的风力
}else{
fl = days[i]._FL;
}
_FLList[i]->setText(fl);
}
update();
}
void Widget::drawTempLineHigh()
{
QPainter painter(ui->widget0404);
painter.setBrush(Qt::red);
painter.setPen(QColor(170, 85, 0));
int sum = 0;
int ava;
int offSet = 0;
int middle = ui->widget0404->height()/2;
for(int i = 0; i < 6; i++){
sum += days[i]._TempHigh.toInt();//6天温度的总和
}
ava = sum / 6;//温度的平均值
QPoint point[6];
for(int i = 0; i < 6; i++){
point[i].setX(_AirqList[i]->x() + _AirqList[i]->width()/2);//计算点的x坐标
offSet = (days[i]._TempHigh.toInt() - ava)*3;
point[i].setY(middle - offSet);//计算点的y坐标
painter.drawEllipse(point[i],2,2);//画出6个点
painter.drawText(point[i], days[i]._TempHigh + "°");//画出当天的最高温度
}
for(int i = 0; i < 5; i++){
painter.drawLine(point[i],point[i+1]);//画出曲线图
}
}
void Widget::drawTempLineLow()
{
QPainter painter(ui->widget0405);
painter.setBrush(Qt::blue);
painter.setPen(QColor(6, 224, 243));
int sum = 0;
int ava;
int offSet = 0;
int middle = ui->widget0404->height()/2;
for(int i = 0; i < 6; i++){
sum += days[i]._TempLow.toInt();//6温度的总和
qDebug() << days[i]._TempLow.toInt();
}
ava = sum / 6;//温度的平均值
QPoint point[6];
for(int i = 0; i < 6; i++){
point[i].setX(_AirqList[i]->x() + _AirqList[i]->width()/2);
offSet = (days[i]._TempLow.toInt() - ava)*3;
point[i].setY(middle - offSet);
painter.drawEllipse(point[i],2,2);
painter.drawText(point[i], days[i]._TempLow + "°");
}
for(int i = 0; i < 5; i++){
painter.drawLine(point[i],point[i+1]);
}
}
//读取天气的数据
void Widget::readHttpRply(QNetworkReply *reply)
{
int reCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();//状态码的捕获
if(reply->error() == QNetworkReply::NoError && reCode == 200){
qDebug() << reCode;
QByteArray readBuf = reply->readAll();//读取天气的数据
parseCurrentWeatherJsonDatanew(readBuf);//解析天气的Json数据
//qDebug() << QString::fromUtf8(readBuf);
}else{
qDebug() << reCode;
QMessageBox mes;
mes.setWindowTitle("错误");
mes.setText("网络请求失败" + QString::number(reCode) + " ");
mes.setStyleSheet("QPushButton {color:black}");//设置按键的样式表
mes.exec();
}
}
//搜索城市
void Widget::on_pushButton_clicked()
{
QString currentCityName = ui->lineEditsearch->text();
QString cityCode = citynames.getCityCodeid(currentCityName);//获取到城市的ID
qDebug() << cityCode;
if(cityCode != NULL){
QString url = "http://v1.yiketianqi.com/api?unescape=1&version=v9&appid=17212311&appsecret=wgJCYY4x&cityid=" + cityCode;
qDebug() << url;
manager->get(QNetworkRequest(QUrl(url)));//发起get请求
}else{
QMessageBox mes;
mes.setWindowTitle("错误");
mes.setText("请输入正确的城市名称");
mes.setStyleSheet("QPushButton {color:black}");//设置按键的样式表
mes.exec();
}
}
void Widget::on_lineEditsearch_returnPressed()
{
on_pushButton_clicked();
}
5.2.1day.h
#ifndef DAY_H
#define DAY_H
#include <QString>
class day
{
public:
day();
QString _Date;
QString _Week;
QString _WeathType;
QString _Temp;
QString _TempLow;
QString _TempHigh;
QString _FX;
QString _FL;
QString _Airq;
QString _Tips;
QString _Hu;
QString _City;
QString _Pm25;
};
#endif // DAY_H
5.2.2day.cpp
#include "day.h"
day::day()
{
}
5.3.1cityname.h
#ifndef CITYNAME_H
#define CITYNAME_H
#include <QMap>
#include <QString>
class CityName
{
public:
CityName();
QMap<QString, QString> cityMap;
QString getCityCodeid(QString cityName);
void initCityName();
};
#endif // CITYNAME_H
5.3.2cityname.cpp
#include "cityname.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
CityName::CityName()
{
}
//获取对应城市的ID
QString CityName::getCityCodeid(QString cityName)
{
//防止多次调用,减小开销
if(cityMap.isEmpty()){
initCityName();//获取城市名字初始化
}
QMap<QString, QString>::iterator it = cityMap.find(cityName);//从Qt的键值对中通过城市的名字寻找
if(it == cityMap.end()){
it = cityMap.find(cityName + "市");//查找后边带市字样的区域
if(it == cityMap.end()){
it = cityMap.find(cityName + "县");//查找后边带县字样的区域
}
if(it == cityMap.end()){
it = cityMap.find(cityName + "区");//查找后边带区字样的区域
}
if(it == cityMap.end()){
return "";//在QMap中发现 名字后边都不带 市 县 区三个关键字的返回空
}
}
return it.value();
}
//获取城市名字初始化
void CityName::initCityName()
{
QFile file(":/citycode.json");
file.open(QIODevice::ReadOnly);
QByteArray rawData = file.readAll();//读取JSON文件保存到QByteArray中
file.close();
QJsonDocument jsonDoc = QJsonDocument::fromJson(rawData);//把QByteArray转成JSONDoc
if(jsonDoc.isArray()){
QJsonArray citys = jsonDoc.array();//把JsonDoc转成QJsonArray
for(QJsonValue val : citys){
if(val.isObject()){
QString cityName = val["city_name"].toString();//解析普通键值对,通过 变量+[" "] 来获取值
QString cityCode = val["city_code"].toString();
cityMap.insert(cityName, cityCode);//将获取到的城市名称和城市ID添加到Qt的键值对中
}
}
}
}