Qt--天气预报

11 篇文章 1 订阅

一、功能介绍

能获取昨天和未来五天的天气情况
就简单获取了一下数据,没有界面处理显示,后续应用的时候再做界面

二、代码

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

三、运行

在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值