基于 Qt / HTTP/JSON 的智能天气预报系统测试报告
目录
一、项目概述
1.1项目背景
1.2项目目标
二、功能需求
2.1 用户界面功能
2.2 后台功能
三、技术选择
3.1 开发框架与工具
3.2 第三方 API
四、UI设计
4.1界面展示
4.2stylesheet样式
五、代码实现
1.构造函数
2.网络请求响应处理函数
3.处理json数据
4.更新UI数据
5.城市搜索按钮实现
6.鼠标左键拖动窗口移动右键关闭
7.事件过滤器绘图
六、结果测试
一、项目概述
1.1项目背景
随着人们对生活品质要求的提高,天气预报已成为日常生活的重要组成部分。通过准确的天气信息,用户可以更好地规划出行、穿衣等日常活动。本项目旨在开发一个基于 Qt 框架的天气预报系统,实现实时天气数据的获取、展示以及历史天气数据的查询功能。
1.2项目目标
-
实现天气数据的 HTTP 请求与解析。
-
展示实时天气信息(包括温度、湿度、风速、空气质量等)。
-
提供未来 7 天天气预报功能。
-
提供用户友好的图形界面。
二、功能需求
2.1 用户界面功能
-
实时天气显示:包括当前温度、湿度、风速、天气状况等。
-
未来天气预报:
-
24 小时天气预报(每小时)。
-
7 天天气预报。
-
-
城市切换:用户可以选择不同的城市查看天气信息。
2.2 后台功能
-
HTTP 请求接口实现,用于获取天气数据。
-
JSON 数据解析模块,将接收到的 JSON 格式天气数据转换为程序可用的数据结构。
三、技术选择
3.1 开发框架与工具
-
Qt 框架:用于 GUI 界面开发和应用程序逻辑实现。
-
QNetworkAccessManager:用于 HTTP 请求(API 调用)。
-
JSON 解析库:使用 Qt 提供的
QJsonDocument
类解析天气数据。
3.2 第三方 API
- 使用天气预报服务提供商的 API(如 OpenWeatherMap、WeatherStack 等),实现天气数据接口调用。
易客云天气API免费天气API接口|天气预报接口|全球天气API接口|气象预警|空气质量我直接使用了这个网站提供的接口。
四、UI设计
4.1界面展示
将整个界面分为四部分,命名如对应部分所示,在控件比较多的情况下,注意排版技巧,分模块会更清晰一些,对控件的命名要规律,在后面功能实现的时候编写代码会更顺。
4.2stylesheet样式
设置边框弧度:
border-radius: 4px;
设置某方向边框弧度:
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
设置背景颜色:
background-color: rgba(60, 60, 60, 100);
父控件影响:
QLabel {
background-color: rgba(0, 200, 200, 200);
border-radius: 4px;
}
五、代码实现
1.构造函数
使用Qt框架创建了一个无边框窗口,固定大小为411x850像素,并设置Arial字体大小为15。创建了一个包含“退出”操作的下拉菜单。点击该菜单项会触发关闭当前窗口的操作。使用QNetworkAccessManager
发送HTTP GET请求到指定天气API接口,以获取实时天气数据。定义了处理网络响应的槽函数readHttpReply
,当网络请求完成时将调用该函数来处理返回的数据。
2.网络请求响应处理函数
-
获取并打印HTTP状态码:从
QNetworkReply
对象中提取HTTP状态码,并将其输出到调试控制台。这有助于在开发和调试过程中快速判断网络请求的成功与否。 -
检查网络请求是否成功:使用
reply->error()
方法检查是否存在网络错误,同时验证HTTP状态码是否为200(表示成功的响应)。如果这两个条件都满足,则认为请求是成功的。 -
处理成功的网络响应:读取所有来自服务器的响应数据,并将其传递给新的解析函数
parseWeatherJsonDataNew(data);
。这表明代码中有专门的函数来解析JSON格式的数据,以便提取有用的信息(如天气数据)进行后续处理或显示。 -
处理失败的网络响应:如果网络请求出现错误(如连接超时、服务器不可达等),则创建并显示一个警告对话框。该对话框提示用户请求失败,并且按钮的文字颜色被设置为红色以增强视觉效果。
3.处理json数据
4.更新UI数据
void Widget::updateUI()
{
ui->labelCurrentData->setText(days[0].mDate+" "+days[0].mWeek);
//解析城市名称
ui->labelCity->setText(days[0].mCity+"市");
//解析当前温度
ui->labelTemp->setText(days[0].mTemp+"°");
ui->labelTempRange->setText(days[0].mTempLow+"℃"+"~"+days[0].mTempHigh+"℃");
//解析天气类型
ui->labelweatherType->setText(days[0].mWeathType);
ui->labelWeatherIcon->setPixmap(mTypeMap[days[0].mWeathType]);
//感冒指数
ui->labelGanmao->setText(days[0].mTips);
//风向
ui->labelFXType->setText(days[0].mFx);
//风力
ui->labelFXType_3->setText(days[0].mFl);
//PM2.5
ui->labelPM25Data->setText(days[0].mPm25);
//湿度
ui->labelShiduData->setText(days[0].mHu);
//空气质量
ui->labelairData->setText(days[0].mAirq);
for(int i=0;i<6;i++){
mWeekList[i]->setText(days[i].mWeek);
mWeekList[0]->setText("今天");
mWeekList[1]->setText("明天");
mWeekList[2]->setText("后天");
QStringList dayList = days[i].mDate.split("-");
mDateList[i]->setText(dayList.at(1)+"-"+dayList.at(2));
int index = days[i].mWeathType.indexOf("转");
// if(index!=-1){
// qDebug()<<days[i].mWeathType.left(index);
// mIconList[i]->setPixmap(mTypeMap[days[i].mWeathType.left(index)]);
// mWeaTypeList[i]->setText(days[i].mWeathType.left(index));
// }
mIconList[i]->setPixmap(mTypeMap[days[i].mWeathType]);
mWeaTypeList[i]->setText(days[i].mWeathType);
QString airQ = days[i].mAirq;
mAirqList[i]->setText(airQ);
if(airQ=="优"){
mAirqList[i]->setStyleSheet("background-color : rgb(150,213,32);border-radius: 7px;");
}
if(airQ=="良"){
mAirqList[i]->setStyleSheet("background-color : rgb(241,224,103);border-radius: 7px;");
}
if(airQ=="轻度污染"){
mAirqList[i]->setStyleSheet("background-color : rgb(255,199,199);border-radius: 7px;");
}
if(airQ=="中度污染"){
mAirqList[i]->setStyleSheet("background-color : rgb(255,17,17);border-radius: 7px;");
}
if(airQ=="重度污染"){
mAirqList[i]->setStyleSheet("background-color : rgb(153,0,0);border-radius: 7px;");
}
mFxList[i]->setText(days[i].mFx);
index = days[i].mFl.indexOf("转");
if(index!=-1){
mFlList[i]->setText(days[i].mFl.left(index));
}else{
mFlList[i]->setText(days[i].mFl);
}
}
update();
}