基于Qt天气预报项目开发

前言


本项目基于QT平台开发的一款天气预报,一个适合小白练手的项目。使用到了技术有HTTP编程、定位API、天气预报API、JSON解析,unicode转化为汉字。分享给大家一起讨论学习;

1、项目界面

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

界面没有选择UI布局,使用代码布局为了加深对QT的熟练,看个人爱好

2、使用讲解

启动界面

搜索城市 :重庆

定位当前城市

3、相关功能实现

QT的网络编程需要 添加一个network

大多数的天气api中不支持自动定位功能,需要手动的设置城市名称,但是这不符合我们实际生活的使用情况,所以在天气api之前我们还需要一个定位ip,这里我使用的是百度ip定位api

3.1、百度ip定位api

https://api.map.baidu.com/location/ip?ak=您的AK&ip=您的IP&coor=bd09ll

AK注册百度开发者平台就可获得

json返回数据如下

{
"address":"CN|\u56db\u5ddd\u7701|\u6210\u90fd\u5e02|None|None|100|100",
"content":{
			"address":"\u56db\u5ddd\u7701\u6210\u90fd\u5e02",
			"address_detail":{
							"adcode":"510100",
							"city":"\u6210\u90fd\u5e02",
							"city_code":75,
							"district":"",
							"province":"\u56db\u5ddd\u7701",
							"street":"",
							"street_number":""
							},
			"point":{
				"x":"104.07274727",
				"y":"30.57899372"
				}
		},
"status":0
}

第一时间发现不懂,但是状态码表示正常,由于本人也是小白经验不足,也没有提示信息,在这如果觉得麻烦可以换成其他api,比如高德api,但是我死磕了两天搞懂了含义,其实返回的是unicode码,了解了原理过后我们就只要把unicode码转换为汉字就ok了,这里我提供一个转换代码

unicode码 转换 汉字

QString filename;
do
   {
        int idx = filename.indexOf("\\u");
        QString strHex = filename.mid(idx, 6);
        strHex = strHex.replace("\\u", QString());
        int nHex = strHex.toInt(0, 16);
        filename.replace(idx, 6, QChar(nHex));
    } while (filename.indexOf("\\u") != -1);

然后得到数据为

{
"address":"CN|四川省|成都市|None|None|100|100",
"content":{
			"address":"四川省成都市",
			"address_detail":{
							"adcode":"510100",
							"city":"成都市",
							"city_code":75,
							"district":"",
							"province":"四川省",
							"street":"",
							"street_number":""
							},
			"point":{
				"x":"104.07274727",
				"y":"30.57899372"
				}
		},
"status":0
}

JSON返回数据

调用代码

    //发送http请求
void Widget::get_city(void)
{
    QNetworkRequest request;
    request.setUrl(QUrl("https://api.map.baidu.com/location/ip?ak=您的AK&ip=您的IP&coor=bd09ll"));
    requst_city->get(request);
}
    //json解析
void Widget::json_city(QNetworkReply *reply)
{
    QString all = reply->readAll();
    
    //unicode 转化为汉字
    QString filename = all;
    do
    {
        int idx = filename.indexOf("\\u");
        QString strHex = filename.mid(idx, 6);
        strHex = strHex.replace("\\u", QString());
        int nHex = strHex.toInt(0, 16);
        filename.replace(idx, 6, QChar(nHex));
    } while (filename.indexOf("\\u") != -1);
     //json解析过程
    QJsonDocument  Document;
    QJsonParseError json_error;
    QJsonDocument json_recv = QJsonDocument::fromJson(all.toUtf8(),&json_error);//解析json对象
    QJsonObject object = json_recv.object();
    if(object.contains("content"))
    {
       QJsonValue value = object.value("content");
       if(value.isObject())
       {
           QJsonObject object_1 = value.toObject();
           if(object_1.contains("address_detail"))
           {
               QJsonValue value_1 = object_1.value("address_detail");
               if(value_1.isObject())
               {
                   QJsonObject object_2 = value_1.toObject();
                   locat_city =object_2.value("city").toString();
               }
            }
       }
    }
    //通过获取了城市自动调用天气数据申请
    get_weather(locat_city);
}

3.2、墨迹天气api

一般天气api有三种手动设置获取天气的方式 1、城市中心经纬度; 2、城市编码; 3、城市名。
个人认为城市名方便就以此为例,对应的为墨迹天气api;

http://autodev.openspeech.cn/csp/api/v2.1/weather?openId=aiuicus&clientType=android&sign=android&city=城市名&needMoreData=true&pageNo=1&pageSize=7

json返回数据如下

{
"code":0,
"msg":"操作成功",
"data":{
	"total":7,
	"sourceName":"墨迹天气",
	"list":[
			{
			"city":"成都",
			"lastUpdateTime":"2022-10-20 18:55:08",
			"date":"2022-10-20",
			"weather":"晴",
			"temp":22.0,
			"humidity":"45%",
			"wind":"北风1级",
			"pm25":58.0,
			"pm10":58.0,
			"low":14.0,
			"high":24.0,
			"airData":"58",
			"airQuality":"良",
			"dateLong":1666195200000,
			"weatherType":0,
			"windLevel":1,
			"province":"四川",
			"moreData":{
			"sunrise":"2022-10-20 07:09:00",
			"sunset":"2022-10-20 18:28:00",
			"precipitation":"0",
			"alert":null
}
},

上面的json数据不完整,本来会有未来七天的,篇幅有限只展示当天的

调用代码

void Widget::get_weather(QString city)
{

    QNetworkRequest request;
    request.setUrl(QUrl(QString("http://autodev.openspeech.cn/csp/api/v2.1/weather?"
                        "openId=aiuicus&clientType=android&sign=android&city=%1"
                        "&needMoreData=true&pageNo=1&pageSize=7").arg(city)));
    requst_weather->get(request);
}
void Widget::json_weather(QNetworkReply *reply)
{
    QString all = reply->readAll();
    QJsonDocument  Document;
    QJsonParseError json_error;
    QJsonDocument json_recv = QJsonDocument::fromJson(all.toUtf8(),&json_error);//解析json对象
    QJsonObject object = json_recv.object();
        if(object.contains("data"))
        {
           QJsonValue value = object.value("data");
           if(value.isObject())
           {
               QJsonObject object_1 = value.toObject();
               if(object_1.contains("list"))
               {
                   QJsonValue value_1 = object_1.value("list");
                   if(value_1.isArray())
                   {
                        for(int i=0; i<7; i++)
                        {
                            QJsonObject weather = value_1.toArray().at(i).toObject();
                            QString strdate = weather.value("date").toString();
                            date[i] = strdate.right(5);
                            weather_type[i] = weather.value("weather").toString();
                            temp[i] = weather.value("temp").toInt();
                            humidity[i] = weather.value("humidity").toString();
                            pm[i] = weather.value("pm25").toInt();
                            int low = weather.value("low").toInt();
                            int high = weather.value("high").toInt();
                            temp_range[i] = QString::number(low)+"~~"+QString::number(high)+"℃";
                            airData[i] = weather.value("airData").toString();
                            airQuality[i] = weather.value("airQuality").toString();
                            wind_type[i] = weather.value("wind").toString();
 
                        }
                   }
                }
           }
        }
}

3.3、调用代码

槽函数设置

//首先请求一个城市定位
    get_city(); 
//每一秒更新一下页面 
    timer_1 = new QTimer;
    connect(timer_1,SIGNAL(timeout()),this,SLOT(data_updata()));
    timer_1->start(1000);
//每300秒更新一下天气请求
    timer_2 = new QTimer;
    connect(timer_2,SIGNAL(timeout()),this,SLOT(get_city()));
    timer_2->start(300000);
    connect(requst_city, SIGNAL(finished(QNetworkReply*)), this, SLOT(json_city(QNetworkReply*)));
    connect(requst_weather, SIGNAL(finished(QNetworkReply*)), this, SLOT(json_weather(QNetworkReply*)));
//搜索其他城市
    connect(psearch,SIGNAL(clicked()),this,SLOT(seach_city()));
//手动定位当前城市,并刷新天气数据 
    connect(plocal, &QToolButton::clicked, [&](){ get_city(); });

界面数据更新代码

void Widget::data_updata()
{
       lab_city->setText(locat_city);
//拿到当前系统时间
       lab_date[0]->setText(QDateTime::currentDateTime().toString("yyyy-MM-dd dddd"));
//这里是对天气图标的显示,如果打包需要把资源添加到项目中,我这里简单显示效果
       lab_weather_type_pic[0]->setPixmap(QPixmap(QString("C:\\Users\\Liu\\Desktop\\code\\QT\\QT_test\\test_city_weather\\img\\%1.png").arg(weather_type[0])));
       lab_wendu->setText(QString::number(temp[0]));
       lab_weather_type->setText(weather_type[0]);
       lab_temp_range[0]->setText(temp_range[0]);
//一些天气指数设置
       lab_wind->setText("风    向:"+wind_type[0]);
       lab_airD->setText("空气指数:"+airData[0]);
       lab_airQ->setText("空气质量:"+airQuality[0]);
       lab_pm->setText("PM2.5   :"+QString::number(pm[0]));
       lab_hum->setText("湿    度:"+humidity[0]);
//获取其他6天的天气情况
       for (int i=1;i<7;i++) {
           lab_weather_type_pic[i]->setPixmap(QPixmap(QString("C:\\Users\\Liu\\Desktop\\code\\QT\\QT_test\\test_city_weather\\img\\%1.png").arg(weather_type[i])));
           lab_temp_range[i]->setText(temp_range[i]);
           lab_date[i]->setText(date[i]);
       }
}

搜索其他城市

这里我写的简单,任意输入一个字符串都会搜索这不对的;
我们应该在这里要去判断输入城市名是否合法性,合法更新界面,不合法提示错误
感兴趣的朋友可以写一下

void Widget::seach_city()
{
    locat_city = lsearch->text();
    get_weather(locat_city);
    data_updata();
}

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

猜你喜欢

转载自blog.csdn.net/m0_60259116/article/details/130013542