基于QT的天气查询系统设计

前言:

     QT获取天气信息一般都是通过调用天气服务器的接口来获取的,网上有很多免费的天气信息API,大致分为两种,一种是xml编码格式的天气信息,一种是Json编码格式的天气信息。Qt对于Json和xml格式文件都有自己的解析方式,而解析Json更为简单、方便,所以选择解析Json格式的天气信息API:http://t.weather.sojson.com/api/weather/city/101010100 (后面最后一个为城市ID)

一、设计目标

   1、用Qt的HTTP通信,获取天气API的内容,再进行解析,实现连续五天的天气查询显示

    2、实现对多个城市的天气信息进行查询,下面提供城市的ID

合肥101220101
北京 101010100
襄阳    101200201
广州    101280101

二、实现过程

1、界面设计

  如下图所示,天气窗口界面由图中①、②、③三部分。其中:

(1)第①部分包括日期框和时间框(QLabel),城市输入框(QComboBox),搜索按钮(QPushButton)。

(2)第②部分是显示今天的天气,包括天气类型显示框,天气图标框、当前温度、温度范围、风力以及空气质量。

(3)第③部分是接下来四天的天气显示地方,每一天由七个QLabel组成,分别显示周几、几月几号、天气图标、温度范围、天气、风力以及空气质量

2、工程目录解析

3、源代码分析

1、通过HTTP获取天气信息的流程(json格式)

(1)创建QNetworkAccessManager对象

          

(2)调用对象方法get/post发送请求(附带一个请求对象)

         ①  选择相应的URL

             

       ②  创建一个请求对象

          

       ③  通过get发送请求

          

(3)当请求完毕后有数据返回时,QNetworkAccessManager对象会发送finished信号,这样就会调用read_data函  数

          

 

(4).在槽函数中获取应答对象并且通过应答对象读取服务器返回的数据

           

2、解析读到的json格式数据

 Json格式的数据是以“{}”包含,Qt把这整体数据叫做“JsonDocument”,相当于目录,并且提供了QJsonDocument类来将信息转换为Qt能够解析的Json数据格式,和QJsonParseError类来检测数据是不是Json格式。“{}”里面存放的是键值对,键值对格式为 key:value  key为键,value为值,value可以是对象,数组, 数,字符串。

(1)判断是否为json格式的数据,如果不是json格式,则程序自动退出

       

(2)json格式一层一层解析

       ①  如果键对应的值为数或字符串时,里面的内容叫做“QJsonObject”,可以由QJsonDocument的“object()”方法来获取

           

        ②  如果键对应的值为数组时,里面的内容叫做“QJsonArray”,再通过遍历将数组将数据取出来(我这里的json数据里面的数组都是存放的键值对,且键值对存放的内容为字符串)

            

         ③  如果键对应的值为对象时,则需要进一步的解析

3、关键代码已经向大家解释了,现在附上源代码

#include "weather.h"
#include "ui_weather.h"

Weather::Weather(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Weather)
{
    ui->setupUi(this);
    //num达到一定值时刷新天气
    num = 0;
    this->rangewendu[0] = ui->range_wendu1;
    this->rangewendu[1] = ui->range_wendu2;
    this->rangewendu[2] = ui->range_wendu3;
    this->rangewendu[3] = ui->range_wendu4;
    this->rangewendu[4] = ui->range_wendu5;

    wtpye[0] = ui->typelb1;
    wtpye[1] = ui->typelb2;
    wtpye[2] = ui->typelb3;
    wtpye[3] = ui->typelb4;
    wtpye[4] = ui->typelb5;

    windlb[0] = ui->windlb1;
    windlb[1] = ui->windlb2;
    windlb[2] = ui->windlb3;
    windlb[3] = ui->windlb4;
    windlb[4] = ui->windlb5;

    aqilb[0] = ui->aqilb1;
    aqilb[1] = ui->aqilb2;
    aqilb[2] = ui->aqilb3;
    aqilb[3] = ui->aqilb4;
    aqilb[4] = ui->aqilb5;

    weeklb[1] =ui->weeklb2;
    weeklb[2] =ui->weeklb3;
    weeklb[3] =ui->weeklb4;
    weeklb[4] =ui->weeklb5;

    datalb[1] = ui->datalb2;
    datalb[2] = ui->datalb3;
    datalb[3] = ui->datalb4;
    datalb[4] = ui->datalb5;

    typepiclb[0] = ui->typepiclb1;
    typepiclb[1] = ui->typepiclb2;
    typepiclb[2] = ui->typepiclb3;
    typepiclb[3] = ui->typepiclb4;
    typepiclb[4] = ui->typepiclb5;

    //天气url
    QUrl url("http://t.weather.sojson.com/api/weather/city/101200201");
    //创建一个请求对象
    QNetworkRequest request(url);
    manager.get(request);

    //关联finished信号
    connect(&manager,&QNetworkAccessManager::finished,this,&Weather::read_data);
    //获取时间以及刷新天气页面
    mtimer.start(1000);
    connect(&mtimer,&QTimer::timeout,this,&Weather::run);

}

Weather::~Weather()
{
    delete ui;
}

//判断空气指数是哪个级别
void Weather::aqi_result(int aqi,int i)
{
    QString aqi_rank;

    if(aqi<=50) {aqi_rank ="优";aqilb[i]->setStyleSheet("background-color:#55ff7f");}
    else if(aqi<=100) {aqi_rank ="良"; aqilb[i]->setStyleSheet("background-color:#ffff00");}
    else if(aqi<=150) {aqi_rank ="轻度污染";aqilb[i]->setStyleSheet("background-color:#ffaa00");}
    else if(aqi<=200) {aqi_rank ="中度污染";aqilb[i]->setStyleSheet("background-color:#ff5500");}
    else if(aqi<=300) {aqi_rank ="重污染";aqilb[i]->setStyleSheet("background-color:#b83d00"); }
    else {aqi_rank ="严重污染";aqilb[i]->setStyleSheet("background-color:#686868"); }
    qDebug()<<aqi_rank;
    aqilb[i]->setText(QString::number(aqi)+" "+aqi_rank);
}

//判断天气
void Weather::type_result(QString type,int i)
{
    QString path;
    if(type == "晴"){path = ":/images/images/晴.png";}
    else if(type=="多云" || type == "晴转多云"){path = ":/image/images/多云.png";}
    else if(type=="阴"){path = ":/image/images/阴.png";}
    else if(type=="阵雨"){path = ":/image/images/阵雨.png";}
    else if(type=="雷阵雨"){path = ":/image/images/雷阵雨.png";}
    else if(type=="小雨"){path = ":/image/images/小雨.png";}
    else if(type=="中雨"){path = ":/image/images/中雨.png";}
    else if(type=="大雨"){path = ":/image/images/大雨.png";}
    else if(type=="暴雨"){path = ":/image/images/暴雨.png";}
    else if(type =="大暴雨"||type =="大到暴雨"){path = ":/image/images/特大暴雨.png";}
    else {path = ":/image/images/扬沙.png";}
    typepiclb[i]->setPixmap(QPixmap(path));
}

void Weather::background_main(QString weatherpic)
{
    if(weatherpic=="晴"||weatherpic == "多云" ||weatherpic == "晴转多云"||weatherpic=="阴")
    {
        this->setStyleSheet("QMainWindow{border-image:url(:/image/images/UI.png)}");
    }
    else  this->setStyleSheet("QMainWindow{border-image:url(:/image/images/UI5.png)}");
}

void Weather::read_data(QNetworkReply *reply)
{
    QByteArray array = reply->readAll();
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(array,&error);

    if(error.error !=QJsonParseError::NoError)
    {
        qDebug("josn error");
        return ;
    }
    QJsonObject obj = doc.object();
    //时间
    QString time = obj.value("time").toString();
    time = time.mid(5,5);
    qDebug()<<time;

    //地区
    QJsonObject cityobj = obj.value("cityInfo").toObject();
    QString city = cityobj.value("city").toString();
    qDebug()<<city;
    QJsonObject dataobj = obj.value("data").toObject();
    //实时温度
    QString wendu = dataobj.value("wendu").toString();
    qDebug()<<wendu;
    ui->wendu->setText(wendu);
    //近一周的天气
    QJsonArray forecast_array = dataobj.value("forecast").toArray();
    for(int i =0;i<5;i++)
    {
        QJsonObject weatherobj = forecast_array.at(i).toObject();
        //最高温度
        QString high = weatherobj.value("high").toString();
        high = high.mid(3);
        qDebug()<<high;
        //最低温度
        QString low = weatherobj.value("low").toString();
        low = low.mid(3,2);
        qDebug()<<low;
        //温度范围
        QString range_wendu = low+"~"+high;
        qDebug()<<range_wendu;
        rangewendu[i]->setText(range_wendu);

        //日期
        QString ymd = weatherobj.value("ymd").toString();
        ymd = ymd.mid(5);
        qDebug()<<ymd;
        //星期几
        week[i] =weatherobj.value("week").toString();
        qDebug()<<week[i];
        if(i!=0){
            weeklb[i]->setText(week[i]);
            datalb[i]->setText(ymd);
        }
        //天气
        QString type = weatherobj.value("type").toString();
        qDebug()<<type;
        if(i == 0) weatherpic = type;
        wtpye[i]->setText(type);
        type_result(type,i);

        //风
        QString fx = weatherobj.value("fx").toString();
        QString fl = weatherobj.value("fl").toString();
        QString wind = fx+fl;
        qDebug()<<wind;
        windlb[i]->setText(wind);

        //空气质量
        int aqi = weatherobj.value("aqi").toInt();
        qDebug()<<aqi;
        aqi_result(aqi,i);

    }
    //地区+日期+星期
    ui->datalb->setText(city+"  "+time+" "+week[0]);
    //设置QMainWindow的背景
    background_main(weatherpic);
    //实时天气
    ui->currweatherlb->setText(weatherpic+"实时");

}

void Weather::on_pushButton_clicked()
{
    QString ip;
    //通过获取城市输入框的当前值来选择哪个城市的URL
    QString city = ui->comboBox->currentText();
    if(city =="北京"){ip = "http://t.weather.sojson.com/api/weather/city/101010100";}
    else if(city=="广州"){ip = "http://t.weather.sojson.com/api/weather/city/101280101";}
    else if(city=="合肥"){ip = "http://t.weather.sojson.com/api/weather/city/101220101";}
    else if(city=="襄阳"){ip = "http://t.weather.sojson.com/api/weather/city/101200201";}
    //天气url
    QUrl url(ip);
    //创建一个请求对象
    QNetworkRequest request(url);
    manager.get(request);

}

void Weather::run()
{

    QString time =  QTime::currentTime().toString("hh:mm:ss");
    ui->timelb->setText(time);
    num++;
    //隔五分钟刷新一次
    if(num>=60*5){on_pushButton_clicked();num = 0;}

}

头文件

#ifndef WEATHER_H
#define WEATHER_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonParseError>
#include <QJsonObject>
#include <QLabel>
#include <QTimer>
#include <QTime>
namespace Ui {
class Weather;
}

class Weather : public QMainWindow
{
    Q_OBJECT

public:
    explicit Weather(QWidget *parent = nullptr);
    ~Weather();

    void aqi_result(int aqi,int i);
    void type_result(QString type, int i);
    void background_main(QString weatherpic);
protected slots:
    void run();
private slots:
    void read_data(QNetworkReply *reply);
    void on_pushButton_clicked();

private:
    Ui::Weather *ui;
    QNetworkAccessManager manager;
    QString weatherpic;
    QString week[5];
    QLabel *rangewendu[5];
    QLabel *wtpye[5];
    QLabel *windlb[5];
    QLabel *aqilb[5];
    QLabel *weeklb[5];
    QLabel *datalb[5];
    QLabel *typepiclb[5];
    QTimer mtimer;
    int num;
};

#endif // WEATHER_H

4、项目效果图

问题咨询及项目源码请加群:

QQ群

名称:IT项目交流群

群号:245022761

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值