目录
[2.1 用户界面功能](#2.1 用户界面功能)
[2.2 后台功能](#2.2 后台功能)
[3.1 开发框架与工具](#3.1 开发框架与工具)
[3.2 第三方 API](#3.2 第三方 API)
一、项目概述
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();
}
5.城市搜索按钮实现

6.鼠标左键拖动窗口移动右键关闭

7.事件过滤器绘图



六、结果测试

