QT实现天气预报

1. MainWindow类设计的成员变量和方法

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

   protected:

形成文本菜单来用来右键关闭窗口
    void contextMenuEvent(QContextMenuEvent* event);

鼠标被点击之后此事件被调用

    void mousePressEvent(QMouseEvent *ev);

移动窗口
    void mouseMoveEvent(QMouseEvent* ev);
    //重写过滤器方法
    bool eventFilter(QObject *watched, QEvent *event);

private slots://信号槽函数
    void onReplied(QNetworkReply* reply);

    void on_btnSearch_clicked();

public:

    void getWeaterInfo(QString cityCode);
    //解析json数据
    void parseJson(QByteArray& byteArray);
    int parseString(QString str);
    //更新UI
    void UpdateUi();
    //检测空气质量
   int checkedQulity(int api);
    //绘制高低温曲线
    void paintHighCurve();
   void paintLowCurve();


   private:
    Ui::MainWindow* ui;

    QMenu* mExitMenu;   // 右键退出的菜单
    QAction* mExitAct;  // 退出的行为
    QPoint m_offset;//鼠标和左上角坐标的偏移距离
    QNetworkAccessManager *m_netAccessManager;
    Today m_today;
    Day m_day[7];

    //星期和日期
    QList<QLabel*> m_weekList;
    QList<QLabel*> m_dateList;

    //天气和天气图标
    QList<QLabel*> m_typeList;
    QList<QLabel*> m_typeIconList;

    //天气污染指数
    QList<QLabel*> m_ApiList;

    //风力和风向
    QList<QLabel*> m_FLList;
    QList<QLabel*> m_FXList;

把UI控件都放到QList集合里面

//将UI控件放到数组里边,方便使用循环进行处理
    m_dateList << ui->lblDate0 << ui->lblDate1 << ui->lblDate2 << ui->lblDate3 << ui->lblDate4 << ui->lblDate5;
    m_weekList << ui->lblWeek0 << ui->lblWeek1 << ui->lblWeek2 << ui->lblWeek3 << ui->lblWeek4 << ui->lblWeek5;
    m_ApiList << ui->lblQuality0 << ui->lblQuality1 << ui->lblQuality2 << ui->lblQuality3 << ui->lblQuality4 << ui->lblQuality5;
    m_typeList << ui->lblType0 << ui->lblType1 << ui->lblType2 << ui->lblType3 << ui->lblType4 << ui->lblType5;
    m_typeIconList << ui->lblTypeIcon0 << ui->lblTypeIcon1 << ui->lblTypeIcon2 << ui->lblTypeIcon3 << ui->lblTypeIcon4 << ui->lblTypeIcon5;
    m_FXList << ui->lblFx0 << ui->lblFx1 << ui->lblFx2 << ui->lblFx3 << ui->lblFx4 << ui->lblFx5;
    m_FLList << ui->lblFl0 << ui->lblFl1 << ui->lblFl2 << ui->lblFl3 << ui->lblFl4 << ui->lblFl5;

    QMap <QString,QString> m_typeMap;

2. 右键退出

void contextMenuEvent(QContextMenuEvent* event);

  mExitMenu->exec(QCursor::pos());
    event->accept();

QMenu* mExitMenu;   右键退出的菜单

 // 右键菜单:退出程序
    mExitMenu = new QMenu(this);//添加一个菜单框
    mExitAct = new QAction();
    mExitAct->setText(tr("退出"));
    mExitAct->setIcon(QIcon(":/res/close.png"));
    mExitMenu->addAction(mExitAct);//把这个行为设置到菜单里面去

    connect(mExitAct, &QAction::triggered, this, [=]() {
        qApp->exit(0); 
    });

3.存放天气信息的类


class Today
{
public:
    Today()
    {
        date = "2022-10-20";
        city = "广州";

        ganmao = "感冒指数";

        wendu = 0;
        shidu = "0%";
        pm25 = 0;
        quality = "无数据";

        type = "多云";

        fl = "2级";
        fx = "南风";

        high = 30;
        low = 18;
    }

    QString date;
    QString city;

    QString ganmao;

    int wendu;
    QString shidu;
    int pm25;
    QString quality;

    QString type;

    QString fx;
    QString fl;

    int high;
    int low;
};

class Day
{
public:
    Day()
    {
        date = "2022-10-20";
        week = "周五";

        type = "多云";

        high = 0;
        low = 0;

        fx = "南风";
        fl = "2级";

        aqi = 0;
    }

    QString date;
    QString week;

    QString type;
    QString ymd;

    int high;
    int low;

    QString fx;
    QString fl;

    int aqi;
};

4.get请求数据

void MainWindow::getWeaterInfo(QString cityName)
{
    QString cityCode=weatherTool::getCityCode(cityName);
    qDebug()<<"cityCode"<<cityCode;
    QUrl url("http://t.weather.itboy.net/api/weather/city/"+cityCode);
    m_netAccessManager->get(QNetworkRequest(url));//发送get请求
}

5.重写void onReplied函数

void onReplied(QNetworkReply* reply);在get请求成功之后此函数被调用

void MainWindow::onReplied(QNetworkReply *reply)
{
    qDebug()<<"onReplied success";
    int status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug()<<"参数: "<<reply->operation();
    qDebug()<<"状态码: "<<status_code;
        qDebug()<<"url: "<<reply->url();
    qDebug()<<"请求头: "<<reply->rawHeaderList();
                                   
    if(reply->error()!=QNetworkReply::NoError||status_code!=200){
        qDebug()<<reply->errorString().toLatin1().data();
        QMessageBox::warning(this,"天气预报","数据请求失败",QMessageBox::Ok);
    }
    else{
        QByteArray all=reply->readAll();

        qDebug()<<"read all : "<<all.data() ;
        parseJson(all);
    }
    reply->deleteLater();

}

在此函数里把请求到的数据全部读出来

6.读出类之后在调用parseJson(all);来进行解析JSON数据

void MainWindow::parseJson(QByteArray &byteArray)
{
    QJsonParseError err;
    QJsonDocument doc=QJsonDocument::fromJson(byteArray,&err);
    if(err.error!=QJsonParseError::NoError){
        qDebug()<<"解析Json出错了";
        return ;
    }

    //Json对象,包括了请求的全部数据
    QJsonObject rootObj = doc.object();
    //qDebug() << rootObj;
    QJsonObject dataObj = rootObj.value("data").toObject();
    QJsonObject yesterdayObj = dataObj.value("yesterday").toObject();
    //Json数组,未来几天的数据
    QJsonArray forecastArray = dataObj.value("forecast").toArray();
    //1.解析日期和城市
   QString str = rootObj.value("time").toString();
    m_today.date= str.split(" ").at(0);
    qDebug()<<"今天:"<<m_today.date;
    m_today.city = rootObj.value("cityInfo").toObject().value("city").toString();

    //2.解析yesterday
    m_day[0].date = yesterdayObj.value("date").toString();//日期
    m_day[0].aqi = yesterdayObj.value("aqi").toDouble();//空气质量,toDouble包括整数型
    m_day[0].type = yesterdayObj.value("type").toString();//天气类型
    m_day[0].week = yesterdayObj.value("week").toString();//星期
    m_day[0].ymd = yesterdayObj.value("ymd").toString();//完整年月日
    //解析最低温度和最高温度
    /*
    QString str = yesterdayObj.value("low").toString();//最低温度
    str = str.split(" ").at(1);//以空格为分割符,去除前面的文字,取出第二个X℃,
    str = str.left(str.length() - 1);//去除后面的摄氏度符号
    mDay[0].low = str.toInt();//传入最低温度
    str.clear();//清除内容
    str = yesterdayObj.value("high").toString();//最高温度
    str = str.split(" ").at(1);//以空格为分割符,去除前面的文字,取出第二个X℃,
    str = str.left(str.length() - 1);//去除后面的摄氏度符号
    mDay[0].high = str.toInt();//传入最高温度
    */
    //简化版
    m_day[0].low = parseString(yesterdayObj.value("low").toString());//最低温度
    m_day[0].high = parseString(yesterdayObj.value("high").toString());//最高温度
    m_day[0].fx = yesterdayObj.value("fx").toString();//风向
    m_day[0].fl = yesterdayObj.value("fl").toString();//风力

    //3.解析forecast中的6天数据

    for (int i = 0; i < 5; ++i) {
        QJsonObject forecastData = forecastArray[i].toObject();
        //跳过0,因为0已经赋值给昨天的数据了
        m_day[i + 1].date = forecastData.value("date").toString();//日期
        //qDebug()<<"time: "<<m_day[i + 1].date;
        m_day[i + 1].aqi = forecastData.value("aqi").toDouble();//空气质量,toDouble包括整数型
        m_day[i + 1].type = forecastData.value("type").toString();//天气类型
        m_day[i + 1].week = forecastData.value("week").toString();//星期
        m_day[i + 1].low = parseString(forecastData.value("low").toString());//最低温度
        m_day[i + 1].high = parseString(forecastData.value("high").toString());//最高温度
        m_day[i + 1].fx = forecastData.value("fx").toString();//风向
        m_day[i + 1].fl = forecastData.value("fl").toString();//风力
        m_day[i + 1].ymd = forecastData.value("ymd").toString();//完整年月日
        //ymd分割成MM/dd
        //QDateTime::fromString(forecastData.value("ymd").toString(), "yyyy-MM-dd").toString("MM/dd");//日期
        //qDebug() << i << mDay[i + 1].date << mDay[i + 1].aqi << mDay[i + 1].type << mDay[i + 1].week << mDay[i + 1].low << mDay[i + 1].high << mDay[i + 1].fx << mDay[i + 1].fl;
        //qDebug() << i << mDay[i].date;
        //qDebug() << mDay[i + 1].ymd;
    }
    //4.解析今天的数据
    m_today.shidu = dataObj.value("shidu").toString();
    m_today.quality = dataObj.value("quality").toString();
    m_today.ganmao = dataObj.value("ganmao").toString();
    m_today.pm25 = dataObj.value("pm25").toDouble();
    m_today.wendu = dataObj.value("wendu").toString().toInt();
    //qDebug() << dataObj;
    //qDebug() << mToday.shidu << mToday.quality << mToday.ganmao << mToday.pm25 << mToday.wendu;
    //注意:forecast中的第2个元素也是今天的数据
    m_today.type = m_day[1].type;
    qDebug()<<"今天的天气是: "<<m_today.type;
    m_today.low = m_day[1].low;
    m_today.high = m_day[1].high;
    m_today.fx = m_day[1].fx;
    m_today.fl = m_day[1].fl;
    //qDebug() << mToday.type << mToday.low << mToday.high << mToday.fx << mToday.fl;
    UpdateUi();

    //更新曲线在搜索城市完成后手动更新曲线
    ui->lblHighCurve->update();
    ui->lblLowCurve->update();
}

解析完JSON数据之后在更新ui(UpdateUi();)

7.更新UI

void MainWindow::UpdateUi()
{
    ui->lblDate->setText(QDateTime::fromString(m_today.date,"yyyyMMdd").toString("yyyy/MM/dd")+" "+m_day[1].week);
    ui->lblCity->setText(m_today.city);
    //更新今天数据
    ui->lblTypeIcon->setPixmap(m_typeMap[m_today.type]);//更新图片
    ui->lblTemp->setText(QString ::number(m_today.wendu));
    ui->lblType->setText(m_today.type);
    ui->lblLowHigh->setText(QString ::number(m_today.low)+"℃ ~ "+QString::number(m_today.high)+"℃");

    ui->lblGanMao->setText("感冒指数: "+m_today.ganmao);
    ui->lblWindFl->setText(m_today.fl);
    ui->lblWindFx->setText(m_today.fx);

    ui->lblPM25->setText(QString::number(m_today.pm25));
    ui->lblShiDu->setText(m_today.shidu);
    ui->lblQuality->setText(m_today.quality);
    //更新六天
    for(int i=0;i<6;i++){
        //更新日期和时间
        m_weekList[i]->setText("周"+m_day[i].week.right(1));//从右边取第一个
        ui->lblWeek0->setText("昨天");
         ui->lblWeek1->setText("今天");
         ui->lblWeek2->setText("明天");

//         //把日期提取出来变成 10/10格式
         QStringList slist=m_day[i].ymd.split("-");
         qDebug()<<slist;
         m_dateList[i]->setText(slist.at(1)+"/"+slist.at(2));

         //更新天气类型
         m_typeList[i]->setText(m_day[i].type);
         m_typeIconList[i]->setPixmap(m_typeMap[m_day[i].type]);//更新图片
//空气质量
        switch (checkedQulity(m_day[i].aqi)) {
        case 1:
            m_ApiList[i]->setText("优");
            m_ApiList[i]->setStyleSheet("background-color: rgb(121,184,0);");
            break;
        case 2:
            m_ApiList[i]->setText("良");
            m_ApiList[i]->setStyleSheet("background-color: rgb(255,187,23);");
            break;
        case 3:
            m_ApiList[i]->setText("轻度");
            m_ApiList[i]->setStyleSheet("background-color: rgb(255,87,97);");
            break;
        case 4:
            m_ApiList[i]->setText("中度");
            m_ApiList[i]->setStyleSheet("background-color: rgb(235,17,27);");
            break;
        case 5:
            m_ApiList[i]->setText("重度");
            m_ApiList[i]->setStyleSheet("background-color: rgb(170,0,0);");
            break;
        case 6:
            m_ApiList[i]->setText("严重");
            m_ApiList[i]->setStyleSheet("background-color: rgb(110,0,0);");
            break;
        }
        //风力风向
        m_FXList[i]->setText(m_day[i].fx);
        m_FLList[i]->setText(m_day[i].fl);
    }

}

//检查空气质量
int MainWindow::checkedQulity(int aqi)
{
    if (aqi >= 0 && aqi <= 50) {
         return 1;
    }else if(aqi > 50 && aqi <= 100){
         return 2;
    }else if(aqi > 100 && aqi <= 150){
         return 3;
    }else if(aqi > 150 && aqi <= 200){
         return 4;
    }else if(aqi > 200 && aqi <= 250){
         return 5;
    }else{
         return 6;
    }
    return -1;
}

8.实现搜索框搜索城市

获取LeCity搜索框输入的数据

void MainWindow::on_btnSearch_clicked()
{
    QString cityName=ui->leCity->text();
    getWeaterInfo(cityName);
}

天气工具类

//天气工具类
class weatherTool{
private:
    //内联静态变量 在占用调用处的内存
    inline static QMap<QString,QString> m_cityMap={};
    static void initCityMap(){
        QFile fd("E:\\code\\citycode.json");
        fd.open(QIODevice::ReadOnly|QIODevice::Text);
        QByteArray allJson=fd.readAll();
        fd.close();
        QJsonParseError err;
        //读出的数据转换为json的
        QJsonDocument doc=  QJsonDocument::fromJson(allJson,&err);

        if(err.error!=QJsonParseError::NoError||!doc.isArray()){
          //不是数组就错误
            qDebug()<<"json数据转换失败...";
            return;
      }  //转换成json数组
        QJsonArray rootArray=doc.array();
      for(int i=0;i<rootArray.size();i++){
            QString cityName = rootArray[i].toObject().value("city_name").toString();
            QString cityCode = rootArray[i].toObject().value("city_code").toString();
            //判断编号是否存在
            if(cityCode.size()>0){
                m_cityMap.insert(cityName,cityCode);
            }
        }

    }

public :
    QString static getCityCode(QString cityName){
        qDebug()<<"cityName"<<cityName;
        if(m_cityMap.isEmpty()){
            qDebug()<< m_cityMap.isEmpty();
            initCityMap();
        }
        if(cityName==""){
            QMessageBox::warning(nullptr,"错误(null)","输入的城市不能为空...",QMessageBox::Ok);
            return "";
        }
  //在map寻找传入的城市名称,返回值可以遍历
        //返回的是map中的多个元素
        QMap<QString, QString>::iterator it = m_cityMap.find(cityName);
        //到结尾了,未找到,加上市,再搜一遍
        if (it == m_cityMap.end()) {
           it = m_cityMap.find(cityName + "市");
        }
        //找到了
        if (it != m_cityMap.end()) {
           qDebug()<<" if (it != m_cityMap.end())";
           return it.value();
        }

        QMessageBox::warning(nullptr,"城市名字错误","输入的城市名字错误...",QMessageBox::Ok);
        //否则
        return "";
    }


};

读取这个文件里面的数据QFile fd("E:\\code\\citycode.json");把city_name和city_code取出来放到QMap集合里面去,之后在和输入的CityName进行查找获得city_code.

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/78437.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

win10系统docker创建ubuntu容器解决开发环境问题

一、win10系统使用docker的原因 最近啊&#xff0c;在学习人工智能-深度学习&#xff0c;用的win10系统进行开发&#xff0c;老是出现一些莫名其妙的问题&#xff0c;无法解决&#xff0c;每天都在为环境问题搞得伤透了脑筋。 说到底还是要使用Linux系统进行开发比较合适。 …

NodeJs导出PDF

&#xff08;优于别人&#xff0c;并不高贵&#xff0c;真正的高贵应该是优于过去的自己。——海明威&#xff09; 场景 根据订单参数生成账单PDF 结果 示例代码 /* eslint-disable no-unused-vars */ /* eslint-disable no-undef */ /* eslint-disable complexity */ const…

【bug】Unity无法创建项目

bug UnityHub无法创建项目 UnityHub无法创建项目 出现的问题&#xff1a;在创建新项目时弹出来一个 无法创建项目 尝试的方法&#xff1a; 刷新许可证 ❌没用退出账号重新登陆 ❌没用重启电脑 ❌没用 最后发现是什么问题呢&#xff1f; 2021.3.3这个版本我之前在资源管理器中…

Arcgis连续数据的分类(求不同值域的面积)

问题描述&#xff1a;如果得到的一个连续的影响数值数据&#xff0c;但是我们想求取某一段值域的面积占比&#xff0c;需要进行以下操作&#xff1a; 1.按照数值重分类&#xff0c;将某段数值变成一个类别 2.栅格转矢量&#xff0c;再求取面积

Kafka 集群搭建过程

前言 跟着尚硅谷海哥文档搭建的Kafka集群环境&#xff0c;在此记录一下&#xff0c;侵删 注意&#xff1a;博主在服务器上搭建环境的时候使用的是一个服务器&#xff0c;所以这篇博客可能会出现一些xsync分发到其他服务器时候的错误&#xff0c;如果你在搭建的过程中出现了错…

【脚踢数据结构】图(纯享版)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;软件配置等领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff01;送给自己和读者的…

能耗监测管理系统在产业园区中的应用分析

摘要&#xff1a;随着电信公司企业级智能化办公系统的不断迭代优化及财务辅助系统与各个业务系统之间的壁垒不断打破、融合&#xff0c;能耗监测管理系统在企业生产运行管理中&#xff0c;为实现企业能耗数据归集&#xff0c;“节能减排、降本增效”提供了系统支撑及可行性保障…

Html+JavaScript实现手写签名

前言 Hello各位&#xff0c;本葡萄又来啦&#xff0c;今天遇到的场景是这样的&#xff1a;在日常业务流程中&#xff0c;经常需要某一流程环节中相关责任人员进行审批签字&#xff0c;早期许多公司为了省事就直接会把这位负责人的签名以键盘打字&#xff08;楷体&#xff09;的…

数据结构—散列表的查找

7.4散列表的查找 7.4.1散列表的基本概念 基本思想&#xff1a;记录的存储位置域关键字之间存在对应关系 ​ 对应关系——hash函数 ​ Loc&#xff08;i&#xff09; H&#xff08;keyi&#xff09; 如何查找&#xff1a; 根据散列函数 H(key) k 查找key9&#xff0c;则访…

easyx图形库基础4:贪吃蛇

贪吃蛇 一实现贪吃蛇&#xff1a;1.绘制网格&#xff1a;1.绘制蛇&#xff1a;3.控制蛇的默认移动向右&#xff1a;4.控制蛇的移动方向&#xff1a;5.生成食物6.判断蛇吃到食物并且长大。7.判断游戏结束&#xff1a;8.重置函数&#xff1a; 二整体代码&#xff1a; 一实现贪吃蛇…

springboot里 运用 easyexcel 导出

引入pom <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version> </dependency>运用 import com.alibaba.excel.EasyExcel; import org.springframework.stereotype.Contr…

【算法篇C++实现】常见排序算法

文章目录 &#x1f680;一、选择排序&#x1f680;二、冒泡排序&#x1f680;三、插入排序&#x1f680;四、希尔排序&#x1f680;五、堆排序&#x1f680;六、归并排序&#x1f680;七、快速排序⛳总结&#xff1a; &#x1f680;一、选择排序 算法精炼每趟从待排序的记录中…

Ceph分布式存储系统优化分析

Ceph支持多种存储访问接口&#xff0c;现有的多种性能测试工具都可用于Ceph的性能测试&#xff0c;如测试块接口性能的fio&#xff0c;iometer等&#xff1b;测试CephFS接口的filebench&#xff0c;fio等;测试对象接口的cosbench等。Ceph有专用的基准测试集CBT&#xff0c;其包…

web实现酷炫的canvas粒子动画背景

文章目录 前言一、particle-bg1. git地址&#xff1a;2. 安装3. 使用4. 完整demo 二、tsParticles1. 源码地址&#xff1a;2. 安装3. 引入4. 使用5. 几个例子5.1 ts粒子五彩纸屑烟花5.2 多粒子产卵器-用tsParticles制作5.3 ts粒子鼠标吸引力5.4 粒子烟花 源码地址完结 前言 粒…

【RP2040】香瓜树莓派RP2040之自定义的短按、双击、长按按键

本文最后修改时间&#xff1a;2022年09月15日 11:02 一、本节简介 本节介绍如何编写一个可以自己选择引脚的短按、双击、长按三种方式的按键驱动。 二、实验平台 1、硬件平台 1&#xff09;树莓派pico开发板 ①树莓派pico开发板*2 ②micro usb数据线*2 2&#xff09;电脑…

【运维】linkis安装dss保姆级教程与踩坑实践

文章目录 一. 安装准备二. 创建用户三. 准备安装包四. 修改配置1. 修改config.sh2. 修改db.sh 五、安装和使用1. 执行安装脚本2. 启动服务3. 查看验证是否成功 六. 报错处理报错一&#xff1a;The user is not logged in报错二&#xff1a;dss接口报错报错三&#xff1a;执行没…

IDEA常用工具配置

IDEA常用工具&配置 如果发现插件市场用不了&#xff0c;可以设置Http Proxy&#xff0c;在该界面上点击”Check connection“并输入的地址&#xff1a;https://plugins.jetbrains.com/ 。 一、常用插件 1、MybatisX Mybaits Plus插件&#xff0c;支持java与xml互转 2、F…

TCP/IP协议组

TCP/IP通信协议是目前最完整、使用最广泛的通信协议。它的魅力在于可使不同硬件结构、不同操作系统的计算机相互通信。TCP/IP协议既可用于广域网&#xff0c;也可用于局域网&#xff0c;它是Internet/Intranet的基石。TCP/IP通信协议事实上是一组协议。 TCP/IP协议可分为5层也可…

日志系统——日志格式化模块设计

一&#xff0c;模块主要成员 该模块的主要作用是对日志消息进行格式化&#xff0c;将日志消息组织成制定格式的字符串。 该模块主要成员有两个&#xff1a;1.格式化字符串。 2.格式化子项数组 1.1 格式化字符串 格式化字符串的主要功能是保存日志输出的格式字符串。其格式化字…

机器学习赋能乳腺癌预测:如何使用贝叶斯分级进行精确诊断?

一、引言 乳腺癌是女性最常见的恶性肿瘤之一&#xff0c;也会发生在男性身上。每年全球有数百万人被诊断出乳腺癌&#xff0c;对患者的生活和健康造成了巨大的影响。早期的乳腺癌检测和准确的诊断对于提高治疗的成功率至关重要。然而&#xff0c;乳腺癌的早期诊断面临着许多挑战…