一、功能介绍
能获取昨天和未来五天的天气情况
就简单获取了一下数据,没有界面处理显示,后续应用的时候再做界面
二、代码
weather.h
#ifndef WEATHER_H
#define WEATHER_H
#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QMap>
#include <QMultiMap>
#include <QPushButton>
#include <QTextEdit>
#include <QHBoxLayout>
class Weather : public QWidget
{
Q_OBJECT
public:
Weather(QWidget *parent = nullptr,QString cityName = "");
~Weather();
/* 属性 */
private:
QPushButton *btnFindWeather; // 查询天气按钮
QPushButton *btnRefreshWeather; // 刷新天气按钮
QTextEdit *txtShowWeather; // 显示天气
QNetworkAccessManager *manager; // 网络管理请求句柄
QHBoxLayout *hLayout; // 水平布局
QWidget *hWidget; // 水平窗口
QString cityName; // 城市名
QString allInfo; // 所有信息
QString date; // 日期
QString fengli; // 风力风向
QString wenduRange; // 温度范围
QString currentWendu;//当前温度
QString weatherType; //天气类型
QString ganmao;//对于感冒提示
bool isGetDataSuccess=false;//是否成功获取数据
QMap<QString,QMap<QString,QString>> dataMap;
QJsonValue forecastData; // 预测的数据
QJsonValue yesterdayData; // 昨天的数据
/* 函数 */
public:
void initWidget(); // 初始化窗口
void setCityName(QString cityName); //设置城市名
QString getCityName(); //获取城市名
QString getDate(); //获取当前日期
QString getFengLi(); //获取风向风力
QString getWenDuRange(); //获取温度范围
QString getTianQiType(); //获取天气类型
QString getCurrentWendu(); //获取当前温度
QString getGanMaoInfo(); //获取感冒提示
QString getAllInfo(); //获取原始的所有字段
bool isGetDataSuccessd(); //是否成功获取数据
void refreshWeather(); //刷新天气 还是之前查询的城市
void getDataMap(); //获取昨天以及未来5天的天气预测
void DebugMap(); //调试打印所有信息
void queryWeather();//查询天气
/* 信号 */
signals:
void SignalgetDataFinised();//获取数据结束的信号
void SignalgetDataSuccessed();//获取数据成功的信号
void SignalgetDataFailed();//获取数据失败的信号
/* 槽函数 */
public slots:
void SltreplyFinished(QNetworkReply *reply);// 网络回复完成
void SltFindWeatherClicked(); // 查询按钮点击
void SltRefreshWeatherClicked(); // 刷新按钮点击
};
#endif // WEATHER_H
weather.cpp
#include "weather.h"
#include <QDebug>
/**
* @brief Weather::Weather
* 构造函数
* @param parent
* @param cityName 要查询的城市名 默认为空
*/
Weather::Weather(QWidget *parent,QString cityName)
: QWidget(parent)
{
this->cityName=cityName;
this->cityName= "安阳"; // 调试用
manager = new QNetworkAccessManager(this); // 新建QNetworkAccessManager对象
connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(SltreplyFinished(QNetworkReply*)));//关联信号和槽
initWidget(); // 初始化窗口
}
Weather::~Weather()
{
}
/**
* @brief Weather::initWidget
* 初始化窗口
*/
void Weather::initWidget()
{
this->setGeometry(0,0,800,480); // 主窗口
hWidget = new QWidget(this);
hWidget->setGeometry(0,0,800,100); // 窗口的大小和位置
/* 水平布局 */
hLayout = new QHBoxLayout(this);
hLayout->setSpacing(400); // 设置间隔
/* 按键 */
btnFindWeather = new QPushButton(this);
btnFindWeather->setText("查询天气");
connect(btnFindWeather,SIGNAL(clicked()),this,SLOT(SltFindWeatherClicked()));
btnRefreshWeather = new QPushButton(this);
btnRefreshWeather->setText("刷新天气");
connect(btnRefreshWeather,SIGNAL(clicked()),this,SLOT(SltRefreshWeatherClicked()));
/* 布局添加按钮 */
hLayout->addWidget(btnFindWeather);
hLayout->addWidget((btnRefreshWeather));
/* 窗口添加布局 */
hWidget->setLayout(hLayout);
/* 文本区域 */
txtShowWeather = new QTextEdit(this);
txtShowWeather->setGeometry(0,100,800,380);
}
/**
* @brief Weather::setCityName
* 设置城市名
* @param cityName
*/
void Weather::setCityName(QString cityName)
{
this->cityName=cityName;
}
/**
* @brief Weather::getCityName
* 获取城市名
* @return
*/
QString Weather::getCityName()
{
return this->cityName;
}
/**
* @brief Weather::getDate
* 获取当前日期
* @return
*/
QString Weather::getDate()
{
return this->date;
}
/**
* @brief Weather::getFengLi
* 获取风力风向
* @return
*/
QString Weather::getFengLi()
{
return this->fengli;
}
/**
* @brief Weather::getWenDuRange
* 获取温度范围
* @return
*/
QString Weather::getWenDuRange()
{
return this->wenduRange;
}
/* 获取天气类型 */
QString Weather::getTianQiType()
{
return this->weatherType;
}
/**
* @brief Weather::getCurrentWendu
* 获取当前温度
* @return
*/
QString Weather::getCurrentWendu()
{
return this->currentWendu;
}
/**
* @brief Weather::getGanMaoInfo
* 获取感冒提示
* @return
*/
QString Weather::getGanMaoInfo()
{
return this->ganmao;
}
/**
* @brief Weather::getAllInfo
* 获取所有接收信息
* @return
*/
QString Weather::getAllInfo()
{
return this->allInfo;
}
/**
* @brief Weather::isGetDataSuccess
* 获取是否获取数据成功
* @return
*/
bool Weather::isGetDataSuccessd()
{
return this->isGetDataSuccess;
}
/**
* @brief Weather::getDataMap
*
* @param ok
* @return
*/
void Weather::getDataMap()
{
if(!this->isGetDataSuccess) // 获取天气不成功
return ;
/* 获取天气成功 */
if(yesterdayData.isObject()) // 昨天的数据是一个对象
{
QJsonObject object = yesterdayData.toObject(); //
QMap<QString,QString>mapvalue; // 一个map数组
mapvalue["high"]=object.value("high").toString(); // 最高温度
mapvalue["low"]=object.value("low").toString(); // 最低温度
mapvalue["fengxiang"]=object.value("fx").toString(); // 风向
mapvalue["fengli"]=object.value("fl").toString(); // 风力
mapvalue["type"]=object.value("type").toString(); // 天气类型
dataMap[object.value("date").toString()]=mapvalue; // 日期 数组下标为日期
}
if(forecastData.isArray()) // 预测的数据是一个数组
{
QJsonArray valueArray=forecastData.toArray(); // 获取json数组
for(int i=0;i<valueArray.count();i++) // 遍历数组
{
QJsonObject object = valueArray.at(i).toObject(); // 第1项是今天的数据
QMap<QString,QString>mapvalue;
mapvalue["high"]=object.value("high").toString(); // 最高温度
mapvalue["low"]=object.value("low").toString(); // 最低温度
mapvalue["fengxiang"]=object.value("fengxiang").toString(); // 风向
mapvalue["fengli"]=object.value("fengli").toString(); // 风力
mapvalue["type"]=object.value("type").toString(); // 天气类型
dataMap[object.value("date").toString()]=mapvalue; // 日期是下标
}
}
}
/**
* @brief Weather::SltreplyFinished
* 网络回复完成槽函数
* @param reply
*/
void Weather::SltreplyFinished(QNetworkReply *reply)
{
this->isGetDataSuccess=false; // 先不成功
allInfo = reply->readAll(); // 获取接收的全部信息
// qDebug() << allInfo; // 打印出全部信息
QJsonParseError err;
QJsonDocument json_recv = QJsonDocument::fromJson(allInfo.toUtf8(),&err);//解析json对象
// qDebug() <<"Json-Error:"<< err.error; // 打印解析错误信息
// qDebug() << "json_recv" << json_recv;
/* 添加到文本区域显示 */
txtShowWeather->setText(QString(QJsonDocument(json_recv).toJson(QJsonDocument::Compact)));
if(!json_recv.isNull()) // json字符串不为空
{
QJsonObject object = json_recv.object();
if(object.contains("data")) // 是否包含data
{
QJsonValue value = object.value("data"); // 获取指定 key 对应的 value
if(value.isObject())
{
QJsonObject object_data = value.toObject(); // 转化为QJsonObject对象
this->cityName=object_data.value("city").toString(); // 城市
this->currentWendu=object_data.value("wendu").toString(); // 当前温度
this->ganmao=object_data.value("ganmao").toString(); // 感冒提示
if(object_data.contains("forecast")) // 是否包含有预测信息
{
QJsonValue value = object_data.value("forecast"); // 获取预测的值
forecastData = value; // 获取预测的值
yesterdayData = object_data.value("yesterday"); // 获取昨天的值
if(value.isArray()) // 值是一个json数组
{
QJsonObject today_weather = value.toArray().at(0).toObject(); // 数组的第一个值
weatherType = today_weather.value("type").toString(); // 获取天气类型
date = today_weather.value("date").toString(); // 获取日期
QString low = today_weather.value("low").toString(); // 获取最低温度
QString high = today_weather.value("high").toString(); // 获取最高温度
/* mid(low.length()-3,4): 从第4个位置开始读取low.length()-3个字符 */
wenduRange = low.mid(low.length()-3,4) +"-"+ high.mid(high.length()-3,4);
QString strength = today_weather.value("fengli").toString(); // 风力
strength.remove(0,8); // 去掉前8个字符
strength.remove(strength.length()-2,2); // 去掉后两个字符
fengli = today_weather.value("fengxiang").toString() + strength; // 风向+ 风力
this->isGetDataSuccess=true; // 获取数据成功
}
}
}
}
}else // json字符串为空
{
qDebug()<<"json_recv is NULL or is not a object !!";
}
reply->deleteLater(); //销毁请求对象
/* 获取天气成功 */
if(isGetDataSuccess)
{
qDebug()<<QString::fromLocal8Bit("获取天气成功");
emit this->SignalgetDataSuccessed();
}
else
{
qDebug()<<QString::fromLocal8Bit("获取天气失败");
emit this->SignalgetDataFailed();
}
emit this->SignalgetDataFinised(); // 获取数据完成
}
/**
* @brief Weather::queryWeather
* 查询天气
*/
void Weather::queryWeather()
{
QString local_city = cityName; //获得需要查询天气的城市名称
char quest_array[256]="http://wthrcdn.etouch.cn/weather_mini?city=";
QNetworkRequest quest;
sprintf(quest_array,"%s%s",quest_array,local_city.toUtf8().data());
quest.setUrl(QUrl(quest_array));
quest.setHeader(QNetworkRequest::UserAgentHeader,"luatao v3S");
/*发送get网络请求*/
manager->get(quest);
}
/**
* @brief Weather::refreshWeather
* 刷新天气还是之前的城市
*/
void Weather::refreshWeather()
{
/* 重新查询 不清空城市就行 */
this->currentWendu.clear();
this->wenduRange.clear();
this->ganmao.clear();
this->fengli.clear();
this->weatherType.clear();
this->allInfo.clear();
queryWeather(); // 查询天气
dataMap.clear();//刷新的清空,待获取时在加载
}
/**
* @brief SltFindWeatherClicked
* 查询天气按钮点击事件
*/
void Weather::SltFindWeatherClicked()
{
qDebug() << "SltFindWeatherClicked" << endl;
queryWeather(); // 查询天气
}
/**
* @brief Weather::SltRefreshWeatherClicked
* 刷新按钮点击
*/
void Weather::SltRefreshWeatherClicked()
{
qDebug() << "SltRefreshWeatherClicked" << endl;
refreshWeather(); // 刷新天气
// DebugMap(); // 打印未来几天的天气情况
}
/**
* @brief Weather::DebugMap
* 打印Map信息
*/
void Weather::DebugMap()
{
getDataMap(); // 获取map数据
/* 打印今天的天气情况 */
qDebug()<<endl;
qDebug()<<"city:"<<this->cityName;
qDebug()<<"wendu:"<<this->wenduRange;
qDebug()<<"currentwendu:"<<this->currentWendu;
qDebug()<<"fengli:"<<this->fengli;
qDebug()<<"weatherType:"<<this->weatherType;
qDebug()<<"ganmao:"<<this->ganmao;
/* 打印昨天和未来几天的天气情况 */
QString str;
foreach (QString key, dataMap.keys()) { // 遍历map的key值 也就是日期
str="date"+key+"[";
foreach (QString key1, dataMap.value(key).keys()) { // 遍历每一天的key值 也就是每一项数据
// qDebug()<<key1<<dataMap.value(key).value(key1);
str+=key1+':'+dataMap.value(key).value(key1)+' '; // 获取每一项的值
}
str+=']';
qDebug()<<str; // 打印每一天的信息
}
/*
city: "安阳"
wendu: ""
currentwendu: ""
fengli: ""
weatherType: ""
ganmao: ""
"date20日星期一[fengli:<![CDATA[3级]]> fengxiang:西南风 high:高温 25℃ low:低温 18℃ type:小雨 ]"
"date21日星期二[fengli:<![CDATA[2级]]> fengxiang:西南风 high:高温 31℃ low:低温 17℃ type:晴 ]"
"date22日星期三[fengli:<![CDATA[2级]]> fengxiang:北风 high:高温 30℃ low:低温 19℃ type:晴 ]"
"date23日星期四[fengli:<![CDATA[2级]]> fengxiang:北风 high:高温 23℃ low:低温 19℃ type:阵雨 ]"
"date24日星期五[fengli:<![CDATA[3级]]> fengxiang:北风 high:高温 22℃ low:低温 18℃ type:雷阵雨 ]"
"获取天气成功"
*/
}
main.cpp