您的位置 首页 > 数码极客

qt中如何获得天气

前言

陶渊明《四时》

春水满四泽,

夏云多奇峰。

秋月扬明晖,

冬岭秀寒松。

看了古人的诗,我不禁也诗兴大发,想要吟诗一首:昨日平安夜,今天圣诞节,立冬没多久,马上要降温。额,回归正题啊,最近我的一些微信群里都在发江苏这边马上要迎来寒潮,要降温十几度的消息,突然就让我对天气变得比较敏感。现在想要查一下天气情况真的是太轻松了,打开手机,即可以在各种app上查到,于是我便想我们的组件库中是不是也可以添加一个天气控件,想到便开始做,于是便有了下面的效果。

效果展示

当然上面为了展示效果,除第一张多云的是真实的实况天气,后面几张都是我改过的天气,目前基本支持所有天气类型,我自己又将其分为如下29类:

//天气类型简化为如下分类,实在不想翻译了,就用数字代替了 enum weather_TYPE { WEATHER_1, //晴 WEATHER_2, //少云 WEATHER_3, //晴间多云、多云 WEATHER_4, //阴 WEATHER_5, //有风、平静、微风、和风、清风 WEATHER_6, //强风/劲风、疾风、大风、烈风 WEATHER_7, //风暴、狂爆风、飓风、热带风暴 WEATHER_8, //龙卷风 WEATHER_9, //阵雨、强阵雨 WEATHER_10, //雷阵雨、雷阵雨伴有冰雹、强雷阵雨 WEATHER_11, //雨夹雪、雨雪天气、阵雨夹雪 WEATHER_12, //小雨、小雨-中雨、毛毛雨/细雨 WEATHER_13, //中雨、中雨-大雨 WEATHER_14, //大雨、大雨-暴雨 WEATHER_15, //暴雨、暴雨-大暴雨、大暴雨、特大暴雨、大暴雨-特大暴雨、极端降雨 WEATHER_16, //阵雪 WEATHER_17, //雪、小雪、小雪-中雪 WEATHER_18, //中雪、中雪-大雪 WEATHER_19, //大雪、大雪-暴雪 WEATHER_20, //暴雪 WEATHER_21, //雾、轻雾 WEATHER_22, //浓雾、强浓雾、大雾、特强浓雾 WEATHER_23, //霾、中度霾、重度霾、严重霾 WEATHER_24, //冻雨 WEATHER_25, //沙尘暴、强沙尘暴、 WEATHER_26, //浮尘、扬沙 WEATHER_27, //热 WEATHER_28, //冷 WEATHER_29, //未知 };

为了使每一类的天气状况更加形象具体,为了使控件更加的大气美观,如上面的动图所示,每一类都有特定的动画,共计29种动画。当然大家如果不喜欢这些默认的动画的话,也可以换成任意自己喜欢的图片或动画,只需要替换相应的资源即可。

天气查询功能如何实现?

要想制作实时天气控件,首先要能获取到实时天气状况,那么怎么获取实时天气状况呢?我们自然而然的想到是从网上获取,从某个网页上获取。因此我们首先要先找到能够为我们提供天气查询功能的网页,我从网上找到很多提供类似功能的网站,最后还是感觉如下两个网站比较靠谱,主要还是免费:

  • 心知天气
  • 高德地图天气查询

这两个网站都需要注册才能使用相关的api,其中高德地图每天查询上限是10万次,即使我们每秒查一次也才86400次,完全够用,请求格式如下,其中key的内容被我用xxxxxxxxx代替:

;extensions=base&city=南京

心知天气api好像是每秒限制20次,但是他免费的api返回的数据太少,只有天气类型和温度,其他一概没有,大家酌情自己选择。请求格式如下,其中key的内容被我用xxxxxxxxxx代替:

;language=zh-Hans&unit=c&location=南京

有了能够获取数据的地方以后,那么该怎么通过Qt程序向网页请求数据呢?这时候就需要使用QtNetwork模块,其中主要用到如下三个类:

#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkReply>

这三个类的具体作用我不再详解,大家可以自行了解一下,或者下次我再单独的讲解,主要功能就是向网页发送请求并处理回复,具体使用方法如下:

m_pManager = new QNetworkAccessManager(this); connect(m_pManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); // 查询天气 void Weather::requestWeather() { QString strCity = m_strCityName; //城市名称 //char szQuest[256] = ";language=zh-Hans&unit=c&location=";//心知天气api,每分钟20次好像,但是免费的接口返回的数据太少 char szQuest[256] = ";extensions=base&city="; //高德地图天气查询api,extensions=base表示实况天气,每日限值调用10万次 sprintf(szQuest, "%s%s", szQuest, ().data()); QNetworkRequest quest; que(QUrl(szQuest)); que(QNetworkRequest::UserAgentHeader, "RT-Thread ART"); m_pManager->get(quest); }

上面我们向网页发送请求以后,网页会给我返回相关的数据,数据一般都是JSON格式,以高德地图为例,其天气查询api返回的JSON数据格式如下:

{ "status": "1", "count": "1", "info": "OK", "infocode": "10000", "lives": [ { "province": "江苏", "city": "南京市", "adcode": "320100", "weather": "多云", "temperature": "6", "winddirection": "东", "windpower": "≤3", "humidity": "52", "reporttime": "2020-12-26 00:26:47" } ] }

Qt也为我们提供了一些很方便的类来解析JSON数据:

#include <QJsonDocument> #include <QJsonobject> #include <QJsonArray>

JSON文档可以从它的基于文本的表示使用QJsonDocument::fromJson()转换为QJsonDocument,QJsonObject类用于封装JSON对象,QJsonArray类用于封装JSON数组。同样以解析上面JSON格式的天气数据为例,代码如下:

void Weather::replyFinished(QNetworkReply *reply) { QString strReply = reply->readAll(); //qDebug() << strReply; //解析JSON QJsonParseError error; //转换为JSON文档 QJsonDocument document = QJsonDocument::fromJson(), &error); //未发生错误就解析 if (!document.isNull() && == QJsonParseError::NoError)) { //心知天气JSON解析 // if ()) // { // //转换为JSON对象 // QJsonObject object = document.object(); // if ("results")) // { // QJsonArray resultsArray = object["results"].toArray(); // foreach (const QJsonValue & value, resultsArray) // { // QJsonObject tempObj = value.toObject(); // if ("now")) // { // QJsonValue nowValue = ("now"); // QJsonObject nowItem = nowValue.toObject(); // qDebug()<< ZH_CN("天气 = ") << nowItem["text"].toString(); // qDebug()<< ZH_CN("温度 = ") << nowItem["temperature"].toString(); // } // else // qDebug() << "error 2"; // qDebug() << "last upadte = " << tempObj["last_update"].toString(); // } // } // else // qDebug() << "error 1"; // } //高德地图JSON解析 if ()) { //转换为JSON对象 QJsonObject object = document.object(); if ("lives")) { QJsonArray resultsArray = object["lives"].toArray(); foreach (const QJsonValue & value, resultsArray) { QJsonObject tempObj = value.toObject(); QString str; //qDebug()<< ZH_CN("天气 = ") << tempObj["weather"].toString(); //qDebug()<< ZH_CN("温度 = ") << tempObj["temperature"].toString(); m_strWeather = tempObj["weather"].toString(); str = m_strWeather; str += " "; str += tempObj["temperature"].toString(); str += ZH_CN("°"); m_pWeather_Label->setText(str); //qDebug()<< ZH_CN("风向 = ") << tempObj["winddirection"].toString(); //qDebug()<< ZH_CN("风力 = ") << tempObj["windpower"].toString(); str = tempObj["winddirection"].toString(); str += ZH_CN("风"); str += " "; str += tempObj["windpower"].toString(); str += ZH_CN("级"); m_pWind_Label->setText(str); //qDebug()<< ZH_CN("湿度 = ") << tempObj["humidity"].toString(); str = ZH_CN("湿度: "); str += tempObj["humidity"].toString(); str += "%"; m_pHumidity_Label->setText(str); //qDebug()<< ZH_CN("省份 = ") << tempObj["province"].toString(); //qDebug()<< ZH_CN("城市 = ") << tempObj["city"].toString(); //qDebug()<< ZH_CN("更新时间 = ") << tempObj["reporttime"].toString(); str = tempObj["province"].toString(); str += " "; str += tempObj["city"].toString(); str += " "; str += tempObj["reporttime"].toString(); m_pTime_Label->setText(str); changeBackground(m_strWeather); } } else qDebug() << ZH_CN("天气数据解析失败!"); } } else qDebug() << ZH_CN("请求天气数据是发生错误!"); }

页面及动态背景如何实现?

基本控件创建及窗口布局实现:

void Weather::initUI() { m_pBackground_Label = new QLabel(this);//背景图片标签 m_pBackground_Label->setScaledContents(true); m_pWeather_Label = new QLabel(this); //天气和温度标签 m_pWind_Label = new QLabel(this); //风向和风力标签 m_pHumidity_Label = new QLabel(this); //湿度标签 m_pTime_Label = new QLabel(this); //天气更新时间和地名标签 QFont font("Microsoft YaHei", 16, QFont::Bold); QPalette palette; (QPalette::WindowText, QColor(255, 255, 255)); setLabelStyle(m_pWeather_Label, font, palette); setLabelStyle(m_pWind_Label, font, palette); setLabelStyle(m_pHumidity_Label, font, palette); setLabelStyle(m_pTime_Label, QFont("Microsoft YaHei", 12, QFont::Bold), palette); QWidget *bottom_Widget = new QWidget(this); QVBoxLayout *bottom_VLayout = new QVBoxLayout(); bottom_VLayout->setMargin(0); bottom_VLayout->addWidget(m_pBackground_Label); bottom_Widget->setLayout(bottom_VLayout); QWidget *top_Widget = new QWidget(this); QVBoxLayout *top_VLayout = new QVBoxLayout(); top_VLayout->addWidget(m_pWeather_Label); top_VLayout->addWidget(m_pWind_Label); top_VLayout->addWidget(m_pHumidity_Label); top_VLayout->addWidget(m_pTime_Label); top_Widget->setLayout(top_VLayout); top_Widget->setStyleSheet("QWidget { background: transparent; }"); QGridLayout *main_GLayout = new QGridLayout(); main_GLayout->setMargin(0); main_GLayout->addWidget(bottom_Widget, 0, 0, 1, 1); main_GLayout->addWidget(top_Widget, 0, 0, 1, 1); this->setLayout(main_GLayout); this->setStyleSheet("QWidget { background-color: QColor(56, 56, 56); }"); }

文字标签样式及文字阴影效果设置,文字阴影效果主要为了增加文字和背景的对比度,使文字更加清晰,易于分辨。

//设置标签样式 void Weather::setLabelStyle(QLabel *label, QFont font, QPalette palette) { label->setFont(font); label->setPalette(palette); //添加文字阴影 QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(label); shadowEffect->setOffset(0, 0); shadowEffect->setColor(Qt::black); shadowEffect->setBlurRadius(10); label->setGraphicsEffect(shadowEffect); }

动态背景播放:

m_pMovie = new QMovie(strGifPath); m_pBackground_Label->setMovie(m_pMovie); m_pMovie->setSpeed(100);倍 m_pMovie->start();

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“qt中如何获得天气”边界阅读