Qt实现天气预报

场景简介

WeatherWebService网站提供了获取天气数据的访问接口,不过对于免费的用户来讲,一天只能访问50次,超出之后需要付费。本身就提供了查询城市ID,支持城市列表,通过城市ID可以找到对应城市的照片等多个接口。当然,通过这个接口,可获取天气数据到本地。然后对天气数据进行分析,最终显示到界面上。最终的话可以把界面做的漂亮一点,把功能完善一下,甚至可以做一些可视化的数据分析,提供出行建议等。由于上网不是很方便,这里只做了基本的功能,界面也做的略显ugly。除了访问接口之外,网站还提供了接口说明,天气图标,城市图标等资源。
对于用户来讲,呈现的功能有,输入全国任一城市,单击查询按钮,界面将显示实时的温度、日期、图标;当天的天气情况、温度范围、风力大小、以及一些温馨提示;关于城市的简介、城市的图片(我没做)。默认情况下显示的是西安的天气情况。

步骤与思路

1.从网站接口获取天气数据,使用到的是Qt实现Http请求的知识,即本地计算机作为客户端向该服务器发送Http请求,服务器响应天气数据,因此客户端需要接收并保存。发送Http请求的方式有多种,可以使用Post带参数(指哪个城市)结合网站提供的getweather方法来访问,也可以使用get请求,直接将城市名作为Url的一部分,交给Qt来解析。我用的是第二种方法。
2.获取到的天气数据其实是xml文件,用到的是C7—Qt中使用XML格式文档的知识,就是如何读取本地的xml文件,从中获得可用信息并存储到全局变量中。天气数据xml的构成很简单,一共两级目录,第一级是一些简介,无关痛痒;第二级是天气信息,节点名字统统叫做QString,文本值即有效信息。通过数数的方式判断数据内容。如下图所示。

3.根据全局变量中的数据刷新界面,多数界面部件是QLabel,该显示图的显示图,显示字的显示字即可。具体的步骤结合代码及其注释。

总结与思考

提供几个基于本案例可以拓展的点,和一些开发过程中遇到的值得注意的问题。
1.关于软件功能,界面可仿其他的天气预报软件稍加藻饰,可以结合Qt可视化数据分析做一些统计分析的部件,可以计算一下农历显示。有一个城市风貌的图片我没做,可以结合WeatherWebService网站提供的资源完善一下。
2.关于软件实现,可以尝试使用post带参请求,了解更多网络知识。可以使用xml的第二种stream的方式读取文件。可以尝试其他网站的接口。
3.QLabel设置Text值的时候请注意,给的参数为QString,这个QString过长的话,部件不换行会拉的很长。让部件与文本自适应,自动换行,自动调整大小。如下:

 labelName->adjustSize();//控件大小与内容自适应labelName->setWordWrap(true);//自动换行labelName->setAlignment(Qt::AlignTop);

4.Qt进行文件读写的IO操作,请注意,文件名有特殊字符,将会导致QIODevice::write (QFile, “woshi.xml”): device not open。另外还要注意,从服务器获取数据,相当于是服务器回来的数据要写入本地文件,对于天气数据的分析相当于是要读取同一个本地文件。那必须保证读操作与写操作之间不发生冲突,否则会出现各种错误。如何保证呢?可以等服务器数据传输finish,即发出fnish信号的时候设置状态标志,使用定时器或者线程监测这个标志,直到写完在进行读操作。也可以在finish信号的槽函数中调用分析数据的函数。对于这个小案例,用的是第二种方法。
5.天气数据xml中的标点符号是中文输入的,在数据分析时要注意。使用到xml和network的类,记得现在.pro文件中

效果

代码

main文件

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

.h文件

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QFile>
#include <QMessageBox>
#include <QDateTime>
#include <QDate>
#include <QDomDocument>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
private:Ui::Widget *ui;QNetworkAccessManager *manager;QNetworkReply *reply;QFile *myFile;//xml写QString str_utl;//网址字符串QString filename;//xml文件名QString def_city;//默认城市名QString iconPath;//天气图标ICONQString strProvince;//省份QString strCity;//城市名QString strTempr;//温度范围QString strWeather;//今日天气QString strIcon;//图标名字QString strWind;//风力QString strCurWeather;//实时天气QString strTips;//温馨提示QString strCityHistory;//城市历史void Init();//初始化函数void myHttpGetWeather(QString);//http请求下载xml天气文件void myiRefreshUi();//根据xml文件的解析结果刷新界面bool myDecodeXml();//解析xml文件
private slots:void doProcessReadyRead();void doProcessError(QNetworkReply::NetworkError);void doProcessFinished();void on_query_btn_clicked();
};
#endif // WIDGET_H

.cpp文件

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);Init();}
Widget::~Widget()
{delete ui;
}
void Widget::Init()
{str_utl.clear();filename.clear();def_city.clear();strProvince.clear();strCity.clear();strWind.clear();strTempr.clear();strWeather.clear();strIcon.clear();strCurWeather.clear();strTips.clear();strCityHistory.clear();iconPath.clear();ui->lab_cityHistory->adjustSize();//控件大小与内容自适应ui->lab_cityHistory->setWordWrap(true);//自动换行ui->lab_cityHistory->setAlignment(Qt::AlignTop);iconPath = QString(":/myWeather/");str_utl.append("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName=");filename = QString("woshi.xml");//获取到的天气数据def_city = "西安";myFile = new QFile(this);myFile->setFileName(this->filename);//获取或创建文件manager = new QNetworkAccessManager(this);if(filename.isEmpty()){return;}//获取默认城市 上海市的天气,并据此初始化各个界面部件myHttpGetWeather(def_city);//各界面部件初始化
//    myiRefreshUi();
}
void Widget::myHttpGetWeather(QString str_city)//str = 城市名
{QString current_addr;QUrl myUrl;QNetworkRequest myReq;//准备网络请求current_addr.clear();current_addr.append(str_utl).append(str_city);//当前查询城市网址myUrl.setUrl(current_addr);//设置网络请求的urlmyReq.setRawHeader(QByteArray("User-Agent"),QByteArray("MyOwnBrowser 1.0"));//设置http包的请求头myReq.setUrl(myUrl);bool ret = myFile->open(QIODevice::WriteOnly|QIODevice::Truncate);//以重写的方式打开,在写入新的数据时会将原有if(!ret){QMessageBox::warning(this,"warning","myHttpGetWeather失败!");return;}reply = manager->get(myReq);//发送http get请求connect(reply,SIGNAL(readyRead()),this,SLOT(doProcessReadyRead()));//数据来临的信号,IO操作大多数都是这个信号connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(doProcessError(QNetworkReply::NetworkError)));connect(reply,SIGNAL(finished()),this,SLOT(doProcessFinished()));//传输(一次应答)完成}
//根据所得xml天气信息刷新界面
void Widget::myiRefreshUi()
{//获取当前时间QDateTime c_time = QDateTime::currentDateTime();QString str_week = c_time.toString("ddd");//获取星期QDate date = QDate::currentDate();QString labDataTime;labDataTime.append(QString::number(date.year()));labDataTime.append("年");labDataTime.append(QString::number(date.month()));labDataTime.append("月");labDataTime.append(QString::number(date.day()));labDataTime.append("日");labDataTime.append(" ");labDataTime.append(str_week);//获取xml天气信息if(!myDecodeXml()){return;}//刷新界面//0.刷新省份城市QString tempCity;tempCity = strProvince.append(" ");tempCity = tempCity.append(strCity);ui->url_edit->setText(tempCity);//1.刷新时间界面ui->lab_Datatime->setText(labDataTime);//2.刷新天气图标QString tempIconPath = iconPath;tempIconPath.append(strIcon);qDebug()<<tempIconPath;QPixmap pix(tempIconPath);pix = pix.scaled(QSize(100,100));ui->lab_wetherIcon->setPixmap(pix);//3.刷新实时温度值qDebug()<<"实时天气情况:"<<strCurWeather;strCurWeather.remove("今日天气实况:");QStringList list1 = strCurWeather.split(";");//此处是中文输入下的分号QString tempTempr=list1.at(0);QStringList list2 = tempTempr.split(":");//此处是中文输入下的冒号QString realTempr = list2.at(1);qDebug()<<list1.at(0)<<list2.at(1);ui->lab_realTemp->setText(realTempr);//4.刷新温度值ui->lab_tempRange->setText(strTempr);//5.刷新今日天气ui->lab_wethStatus->setText(strWeather);//6.刷新风力ui->lab_wind->setText(strWind);//7.刷新温馨提示ui->lab_tips->setText(strTips);//8.刷新城市历史ui->lab_cityHistory->setText(strCityHistory);//9.刷新城市照片
}
//解析xml文件,为全局变量赋值
bool Widget::myDecodeXml()
{if(myFile->isOpen()){myFile->close();}bool ret = myFile->open(QIODevice::ReadWrite);//以重写的方式打开,在写入新的数据时会将原有if(!ret){QMessageBox::warning(this,"warning","myDecodeXml打开失败!");return false;}QDomDocument doc("yxx");//定义doc对象,初始化名字QString error;int line, column;bool isLot = doc.setContent(myFile, &error, &line, &column);//将文件与QDomDocument类关联if(!isLot){//关联xml文件失败myFile->close();qDebug() << "Error:" << error << "in line " << line << "column" << column;QMessageBox::warning(this,"waring","myDecodeXml关联失败");return false;}myFile->close();QDomElement firstElem = doc.documentElement();//获取到了<ArrayOfString>一级目录QDomNodeList secondList = firstElem.childNodes();//获取全部二级目录<QString>for (int i = 0; i < secondList.count(); ++i) {QDomElement secondElem = secondList.at(i).toElement();//获取二级目录节点的属性值管理者domElementif(i==0){//获取省份strProvince = secondElem.text();}if(i==1){//获取城市名strCity = secondElem.text();}if(i==5){//获取温度strTempr = secondElem.text();}if(i==6){//获取天气情况QString tempStr;tempStr = secondElem.text();QStringList list = tempStr.split(" ");strWeather = list.at(1);}if(i==7){//获取风力strWind = secondElem.text();}if(i==8){//获取天气图标QString tempIcon = secondElem.text();QStringList list3 = tempIcon.split(".");QString tempIcon2 = list3.at(0);strIcon = tempIcon2.append(".png");}if(i==10){//获取实时天气情况strCurWeather = secondElem.text();}if(i==11){//获取温馨提示strTips = secondElem.text();}if(i==22){//获取城市介绍strCityHistory = secondElem.text();}}qDebug()<<"执行完毕xmldecode";return true;
}
//查询按钮槽函数
void Widget::on_query_btn_clicked()
{//获取地址QString city = ui->url_edit->text();//获取城市名字if(!city.isEmpty()){myHttpGetWeather(city);//获取当前城市的xml天气文件}
}
//数据来临槽函数
void Widget::doProcessReadyRead()
{//读取应答数据,并且写入文件中while(!reply->atEnd()){QByteArray ba = reply->readAll();myFile->write(ba);}
}
//过程出错槽函数
void Widget::doProcessError(QNetworkReply::NetworkError err)
{qDebug()<<"接收过程出错"<<reply->errorString();qDebug()<<err;
}
//请求过程结束信号
void Widget::doProcessFinished()
{qDebug()<<"接收数据完毕!";myFile->close();//强制刷新myiRefreshUi();
}

ui文件

C8—Qt实现天气预报相关推荐

  1. Qt实现天气预报与PM2.5监测系统(6)系统界面设计

    Qt实现天气预报与PM2.5监测系统(6)系统界面设计 系统UI设计 一个图形化的应用,界面设计非常重要.现在软件企业一般有专门的UI设计师,交互设计师. 首先用绘图软件设计出软件界面的设计稿,确定色 ...

  2. Qt之天气预报——界面优化篇(含源码+注释)

    一.界面优化效果 下方为界面优化完成和优化前的效果对比. 优化前: 优化后: 二.优化内容 添加标题栏 添加图片(图图标素材源自阿里巴巴矢量图标库) 更新UI内容(微调大小.布局比例) 添加鼠标事件函 ...

  3. 【QT学习笔记】基于QT的天气预报

    [QT学习笔记]基于QT的天气预报 前言 那就开始吧! 先看一下效果 颜面最重要,画个UI 构造实现 怎么开始? 开始解析数据 关于城市切换 ok 最后源码献上 感谢 前言 学习qt已经有一段时间了, ...

  4. 玩转 ESP32 + Arduino (四) 电容按键 霍尔传感器 外部中断 延时 脉冲检测

    一. 电容输入 touchRead(pin) 及电容输入中断touchAttachInterrupt(pin, TSR , threshold) ESP32专门提供了电容触摸传感器的功能, 共有T0, ...

  5. 网络天气预报项目笔记(Qt)

    项目简介: 1,使用Qt设计一款天气预报的程序,主要包括: 界面显示:当日天气情况.空气质量等级.温湿度等空气指数.每日祝福语以及未来几日天气预报:根据近几日的温度数据绘制温度曲线:支持搜索指定城市功 ...

  6. 【QT开发专题-天气预报】14. 请求天气数据

    本专栏将会在未来4个月内,完成以下几个 Qt 项目: <天气预报> <文本编辑器> <俄罗斯方块> <绘图板> <网络聊天室> <串口 ...

  7. 【QT开发专题-天气预报】15. 解析天气数据

    本专栏将会在未来4个月内,完成以下几个 Qt 项目: <天气预报> <文本编辑器> <俄罗斯方块> <绘图板> <网络聊天室> <串口 ...

  8. 【QT开发专题-天气预报】16.更新 UI 界面

    本专栏将会在未来4个月内,完成以下几个 Qt 项目: <天气预报> <文本编辑器> <俄罗斯方块> <绘图板> <网络聊天室> <串口 ...

  9. 【QT开发专题-天气预报】17. 获取城市编号

    本专栏将会在未来4个月内,完成以下几个 Qt 项目: <天气预报> <文本编辑器> <俄罗斯方块> <绘图板> <网络聊天室> <串口 ...

最新文章

  1. 2022-2028年中国加气站行业市场研究及前瞻分析报告
  2. C++多线程:异步操作std::async和std::promise
  3. 【 MATLAB 】filter 函数介绍(一维数字滤波器)
  4. 为TIF、JPG图片添加地理坐标/平面直角坐标
  5. java命令查看环境变量 user.home file.encoding等参数值
  6. 前端学习(1749):前端调试值之如何查看整站的资源和编辑
  7. python(c++)刷题+剑指offer
  8. 百度SEO站群爱叶解析接口php网站源码
  9. 微软认证学习资料大集合(软件+资料)
  10. linux 网络端口全连接扫描,端口全连接扫描程序(Linux, socket):TCP的connect方式...
  11. codeblock异常关闭,重新开机,启动时提示有另外的实例在运行的解决办法。
  12. 饿了么的谁去拿外卖源码
  13. VBA代码行号显示 VBA代码助手独家功能
  14. html页面弹出 聊天框,网页弹出在线交流聊天窗口的功能如何实现 - 快商通
  15. [问题]Make sure that `gem install pg -v '0.17.1'` succeeds before bundling.
  16. Linux内核API之class_create与class_destroy
  17. 纸壳CMS现已支持自定义扩展字段
  18. [Python3] Matplotlib —— (四) 可视化异常处理
  19. 若依后台管理系统总结
  20. 湖北公安机关出台10条措施服务民营经济发展

热门文章

  1. HTML+CSS+JavaScript实现模态框(可拖拽)
  2. 社交游戏的排行榜设计和实现:mysql数据库的应用
  3. 高等数学:学习步骤(持续更新)
  4. JAVA毕业设计(源码+数据库)
  5. java旧版本下载官网地址
  6. echarts 树图使用心得
  7. 基于安卓app开发项目(在线数独对战游戏平台)的毕业设计(附源码)
  8. ZBrush教程视频教程-ZBrush教程教程下载
  9. 小程序获取当前时间及获取当前日期
  10. 计算机设备维护论文前言,机房计算机维护论文