文章目录
- 一、功能介绍
- 二、代码
- 三、运行
一、功能介绍
能获取昨天和未来五天的天气情况
就简单获取了一下数据,没有界面处理显示,后续应用的时候再做界面
二、代码
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_OBJECTpublic: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 对应的 valueif(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