IMX6ULL-QT项目之天气预报运行到开发板

布局: 

 

IP查询API:

                因为天气预报对定位的要求不是很高,我们就可以使用IP地址归属地来查询当前位置,而且位置信息我们在查询天气的时候也要用到。这里给大家提供一个IP地址归属地数据查询的API,使用方法非常简单。

                API:http://whois.pconline.com.cn/ipJson.jsp?ip

               使用说明:http://whois.pconline.com.cn/

天气API:

                获得本地的天气信息,可以调用跟天气相关的API。这里给大家提供一个中华万年历API。天气的API有很多,为什么给大家推荐使用这个API,第一,数据和中国天气网(www.weather.com.cn)一致,第二,返回的数据是json格式,方便解析,第三,查询方便,使用城市名称或者城市id即可查询。(如何网页打开是乱码,没事,可以在QT中修改编码问题)

通过城市名字获得天气数据,json数据
http://wthrcdn.etouch.cn/weather_mini?city=龙岩

通过城市id获得天气数据,json数据,需要城市ID
http://wthrcdn.etouch.cn/weather_mini?citykey=101010100

网络需要用到的类:首先工程加入:QT += network

QNetworkAccessManager  //这个类是网络的大管家,所有和网络相关的接口都要围绕他

QNetworkRequest  //发送网络请求,创建网络响应,例如GET - 从指定的服务器中获取数据,POST - 提交数据给指定的服务器处理















QNetworkReply  //用来保存网络请求响应的

QTextCodec  //转换编码的,因为Qt使用Unicode来存储、绘制和操作字符串

IP定位模块代码:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    natManager = new QNetworkAccessManager(this);//natManager在头文件定义,并且一个项目实例化一个就可以了

    QNetworkRequest ipRequest;
    ipRequest.setUrl(QUrl("http://whois.pconline.com.cn/ipJson.jsp?ip"));
    QNetworkReply *natReply = natManager->get(ipRequest);

    connect(natReply,&QNetworkReply::finished,this,&Widget::slotGetRepalyFinished);//应答处理完成后,会发出finished信号
    //connect(natReply,SIGNAL(finished()),this,SLOT(slotGetRepalyFinished()));高版本的QT这种写法不会自动提示信号,上面的写法可用
}

void Widget::slotGetRepalyFinished()
{
    QNetworkReply *reply = (QNetworkReply *)sender();
    QTextCodec *codec = QTextCodec::codecForName("gbk");
    QString data = codec->toUnicode(reply->readAll());//上述操作完成后,data里存储的就是Unicode编码的字符串了

    qDebug("%s",data.toStdString().data());
    reply->deleteLater();//用完要删除

    int cityLocation = data.indexOf("city")+7;
    int cityCodeLocation = data.indexOf("cityCode")-4;
    QString cityName = data.mid(cityLocation,cityCodeLocation-cityLocation);//mid是字符串切割函数

    ui->location->setText(cityName);
}

 打印天气模块代码(基于上面的代码):

void Widget::slotGetRepalyFinished()
{
    QNetworkReply *reply = (QNetworkReply *)sender();
    QTextCodec *codec = QTextCodec::codecForName("gbk");
    QString data = codec->toUnicode(reply->readAll());//上述操作完成后,data里存储的就是Unicode编码的字符串了

    qDebug("%s",data.toStdString().data());
    reply->deleteLater();//删除reply,不能在 repyfinished 里直接 delete,要调用 deletelater;

    int cityLocation = data.indexOf("city")+7;
    int cityCodeLocation = data.indexOf("cityCode")-4;
    QString cityName = data.mid(cityLocation,cityCodeLocation-cityLocation);//mid是字符串切割函数

    ui->location->setText(cityName);

    QNetworkRequest weatherRequest;
    weatherRequest.setUrl(QUrl("http://wthrcdn.etouch.cn/weather_mini?city="+cityName));
    QNetworkReply *weatherReply = natManager->get(weatherRequest);
    connect(weatherReply,SIGNAL(finished()),this,SLOT(slotGetWeatherFinished()));

}
void Widget::slotGetWeatherFinished()
{
    //可以用槽函数传入参数QNetworkReply *network代替reply,这样可以不用sender
    QNetworkReply *reply = (QNetworkReply *)sender();//sender函数是返回发出信号的对象
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
    QString data = codec->toUnicode(reply->readAll());//上述操作完成后,data里存储的就是Unicode编码的字符串了

    qDebug("%s",data.toStdString().data());//打印json类型的天气数据
    reply->deleteLater();//删除reply
}

 json数据解析需要的类:

QJsonParseError jsonEeeor;  //解析JSON时的错误
QJsonObject     jsonObject; //封装JSON对象
QJsonDocument   jsonDocument;   //封装JSON文本,The QJsonDocument class provides a way to read and write JSON documents
QJsonValue    jsonData;     //封装JSON值
QJsonArray    iconPic;    //封装JSON数组

json数据解析:

要点:json数据格式里,每一个大括号 { 或者中括号【 看成一个对象obj,多级obj,只要遵循一点,就是在每一级上,将Obj作为一个独立的Obj,使用一样的方式再向其所包含的下一级Obj获取信息。

{//一级大括号
   "data":
        {//二级大括号
            "yesterday":
                {//三级大括号
                    "date":"13日星期二",  //string类型
                    "high":"高温 15℃","fx":"西风",
                    "low":"低温 4℃","fl":"<![CDATA[2级]]>",
                    "type":"多云"
                },
            "city":"保定",
            "forecast": //数组类型
                        [//三级中括号
                            {
                                "date":"14日星期三",
                                "high":"高温 22℃",
                                "fengli":"<![CDATA[3级]]>",
                                "low":"低温 8℃",
                                "fengxiang":"西南风","type":"晴"
                            },
                            {
                                "date":"15日星期四",
                                "high":"高温 25℃",
                                "fengli":"<![CDATA[4级]]>",
                                "low":"低温 6℃",
                                "fengxiang":"西风"
                                "type":"多云",
                            },
                            {
                                "date":"16日星期五",
                                "high":"高温 20℃",
                                "fengli":"<![CDATA[4级]]>",
                                "low":"低温 6℃",
                                "fengxiang":"西北风","type":"多云"
                            },
                            {
                                "date":"17日星期六",
                                "high":"高温 19℃",
                                "fengli":"<![CDATA[3级]]>",
                                "low":"低温 6℃",
                                "fengxiang":"西北风",
                                "type":"晴"
                            },
                            {
                                "date":"18日星期天",
                                "high":"高温 25℃",
                                "fengli":"<![CDATA[2级]]>",
                                "low":"低温 10℃",
                                "fengxiang":"西南风",
                                "type":"晴"
                            }
                        ],
             "ganmao":"感冒易发期,外出请适当调整衣物,注意补充水分。",
             "wendu":"19"//数值类型
        },
     "status":1000,
     "desc":"OK"
}

 解析天气json模块代码(基于上面的代码): 

void Widget::slotGetWeatherFinished()
{
    QNetworkReply *reply = (QNetworkReply *)sender();
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
    QString data = codec->toUnicode(reply->readAll());//上述操作完成后,data里存储的就是Unicode编码的字符串了

    qDebug("%s",data.toStdString().data());
    reply->deleteLater();


    QJsonParseError jsonEeeor;  //解析JSON时的错误
    QJsonObject     jsonObject; //封装JSON对象
    QJsonDocument   jsonDocument;   //封装JSON文本
    QString    jsonData;     //封装JSON值
    QString    iconPic;    //封装JSON数组

    jsonDocument = QJsonDocument::fromJson(data.toUtf8());//数据来源转换成jsonDocument
    if(!jsonDocument.isNull() && jsonEeeor.error == QJsonParseError::NoError){
        qDebug("转换成功!!!");//判断下是否转换成功

        if(jsonDocument.isObject()){
            jsonObject = jsonDocument.object();//把jsonDocument转换成具体的对象jsonObject,就是最外围即第一级的大括号
            jsonObject = jsonObject.value("data").toObject();//第二级大括号“data”看成obj对象

            //解析温度
            jsonData = jsonObject.value("wendu").toString();//jsonData定义了QString类型了,所以toString,wendu里面没有下一级了
            qDebug("%s",jsonData.toStdString().data());
            ui->label_2->setText(jsonData);

            //解析感冒
            jsonData = jsonObject.value("ganmao").toString();
            qDebug("%s",jsonData.toStdString().data());
            ui->text->setText(jsonData);
            
            //昨天
            jsonObject = jsonObject.value("yesterday").toObject();
            jsonData = jsonObject.value("type").toString();
            ui->weather4->setText(jsonData);

            //设置昨天的高低温
            jsonData = jsonObject.value("low").toString().mid(3,2)+"/";
            jsonData = jsonData+jsonObject.value("high").toString().mid(3,2);
            ui->temperature->setText(jsonData);
        }
    }

}

图片的显示需要用到的类:

QStringList  //QStringList类提供字符串列表

QPixmap  //QPixmap类是一种屏幕外图像表示,可以用作绘制设备

显示图片的模块代码:

//如果12张照片都没有天气文字与之对应的,则可以完善图片,或者统一弄一张图片用来显示没有对应的,我统一设置为第13张图片
for (int i=0;i<12;++i) {
                if(jsonData == iconList[i]){
                    iconPic = ":/"+QString::number(i+1)+".png";//QString::number是将数数字(整数、浮点数、有符号、无符号等)转换为QString类型
                    qDebug("%s",iconPic.toStdString().data());//打印图片所在路径
                    break;
                }
                if(i == 11){
                    qDebug("未找到对应的图片");
                    iconPic = ":/"+QString::number(13)+".png";//若找不到就显示第13张设置好的图片
                }
            }
   QPixmap iconPix(iconPic);
   iconPix = iconPix.scaled(ui->weater1->width(),ui->weater1->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
   ui->weater1->clear();
   ui->weater1->setPixmap(iconPix);//setPixmap加载10几K图片会放大图片,所以要用到QPixmap类

void Widget::iconPath()  //头文件定义函数
{
    //和图片的顺序一一对应
    iconList << "中雨"
             << "冰雹"
             << "多云"
             << "大雨"
             << "大雪"
             << "小雨"
             << "晴"
             << "暴雨"
             << "沙尘"
             << "雷雨"
             << "小雨转多云"
             << "雾霾";
}

设置背景用到的类:

QPalette //Qpalete类包含每个小部件状态的颜色组

背景设置代码: 

//第一种:
QPalette Pic;
Pic.setBrush(QPalette::Background,QBrush(QPixmap(":/beijing.png").scaled(this->size())));//路径看自己的
this->setPalette(Pic);

//第二种
this->setStyleSheet("MainWindow{border-image: url(:/beijing.png);}");

最后还需要每隔1小时更新一次数据即可,下面是全部代码:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <QStringList>
#include <QTimer>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

    QNetworkAccessManager *natManager;
    QStringList iconList;
    QTimer m_timer;
    void iconPath();
private:
    Ui::Widget *ui;
public slots:
    void slotGetRepalyFinished();
    void slotGetWeatherFinished();
    void onTimeOut();
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTextCodec>
#include <QString>
#include <QDebug>

#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>

#include <QPixmap>
#include <QPalette>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置定时器每一小时更新一次
    m_timer.start(3600000);//单位ms,一小时3600000ms
    connect(&m_timer,SIGNAL(timeout()),this,SLOT(onTimerout()));

    //设置背景
    QPalette Pic;
    Pic.setBrush(QPalette::Background,QBrush(QPixmap(":/beijing.png").scaled(this->size())));
    this->setPalette(Pic);

    natManager = new QNetworkAccessManager(this);//一个项目实例化一个即可

    QNetworkRequest ipRequest;
    ipRequest.setUrl(QUrl("http://whois.pconline.com.cn/ipJson.jsp?ip"));
    QNetworkReply *natReply = natManager->get(ipRequest);

    connect(natReply,&QNetworkReply::finished,this,&Widget::slotGetRepalyFinished);//应答处理完成后,会发出finished信号
    //connect(natReply,SIGNAL(finished()),this,SLOT(slotGetRepalyFinished()));高版本的QT这种写法不会自动提示信号,上面的写法可用

}

Widget::~Widget()
{
    delete ui;
}
void Widget::onTimeOut()
{
    QNetworkRequest ipRequest;
    ipRequest.setUrl(QUrl("http://whois.pconline.com.cn/ipJson.jsp?ip"));
    QNetworkReply *natReply = natManager->get(ipRequest);
    connect(natReply,&QNetworkReply::finished,this,&Widget::slotGetRepalyFinished);
}
void Widget::slotGetRepalyFinished()
{
    //可以用槽函数传入参数QNetworkReply *network代替reply,这样可以不用sender
    QNetworkReply *reply = (QNetworkReply *)sender();//返回发出信号的对象
    QTextCodec *codec = QTextCodec::codecForName("gbk");
    QString data = codec->toUnicode(reply->readAll());//上述操作完成后,data里存储的就是Unicode编码的字符串了

    qDebug("%s",data.toStdString().data());
    reply->deleteLater();//用完要删除

    int cityLocation = data.indexOf("city")+7;
    int cityCodeLocation = data.indexOf("cityCode")-4;
    QString cityName = data.mid(cityLocation,cityCodeLocation-cityLocation);//mid是字符串切割函数

    ui->location->setText(cityName);

    QNetworkRequest weatherRequest;
    weatherRequest.setUrl(QUrl("http://wthrcdn.etouch.cn/weather_mini?city="+cityName));
    QNetworkReply *weatherReply = natManager->get(weatherRequest);
    connect(weatherReply,SIGNAL(finished()),this,SLOT(slotGetWeatherFinished()));

}

void Widget::slotGetWeatherFinished()
{
    QNetworkReply *reply = (QNetworkReply *)sender();
    QTextCodec *codec = QTextCodec::codecForName("utf-8");
    QString data = codec->toUnicode(reply->readAll());//上述操作完成后,data里存储的就是Unicode编码的字符串了

    qDebug("%s",data.toStdString().data());
    reply->deleteLater();//删除reply,不能在 repyfinished 里直接 delete,要调用 deletelater;


    QJsonParseError jsonEeeor;  //解析JSON时的错误
    QJsonObject     jsonObject; //封装JSON对象
    QJsonDocument   jsonDocument;   //封装JSON文本
    QString    jsonData;     //封装JSON值
    QString    iconPic;    //封装JSON数组

    iconPath();

    jsonDocument = QJsonDocument::fromJson(data.toUtf8());//数据来源转换成jsonDocument
    if(!jsonDocument.isNull() && jsonEeeor.error == QJsonParseError::NoError){
        qDebug("转换成功!!!");//判断下是否转换成功

        if(jsonDocument.isObject()){
            jsonObject = jsonDocument.object();//把jsonDocument转换成具体的对象jsonObject,就是最外围即第一级的大括号
            jsonObject = jsonObject.value("data").toObject();//第二级大括号“data”看成obj对象

            //解析温度
            jsonData = jsonObject.value("wendu").toString();//jsonData定义了QString类型了,所以toString,wendu里面没有下一级了
            qDebug("%s",jsonData.toStdString().data());
            ui->label_2->setText(jsonData);

            //解析感冒
            jsonData = jsonObject.value("ganmao").toString();
            qDebug("%s",jsonData.toStdString().data());
            ui->text->setText(jsonData);

            jsonObject = jsonObject.value("yesterday").toObject();
            jsonData = jsonObject.value("type").toString();
            ui->weather4->setText(jsonData);

            for (int i=0;i<12;++i) {
                if(jsonData == iconList[i]){
                    iconPic = ":/"+QString::number(i+1)+".png";//QString::number是将数数字(整数、浮点数、有符号、无符号等)转换为QString类型
                    qDebug("%s",iconPic.toStdString().data());//打印图片所在路径
                    break;
                }
                if(i == 11){
                    qDebug("未找到对应的图片");
                    iconPic = ":/"+QString::number(13)+".png";//若找不到就显示第13张设置好的图片
                }
            }
            QPixmap iconPix(iconPic);
            iconPix = iconPix.scaled(ui->weater1->width(),ui->weater1->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
            ui->weater1->setPixmap(iconPix);//setPixmap加载10几K图片会放大图片,所以要用到QPixmap绘图类

            //设置高低温
            jsonData = jsonObject.value("low").toString().mid(3,2)+"/";
            jsonData = jsonData+jsonObject.value("high").toString().mid(3,2);
            ui->temperature->setText(jsonData);


            //解析今天和明天的天气
            jsonObject = jsonDocument.object();//把jsonDocument转换成具体的对象jsonObject,就是最外围即第一级的大括号
            jsonObject = jsonObject.value("data").toObject();//重新让jsonObject先变成第一级data的obj对象

            QJsonArray forecast = jsonObject.value("forecast").toArray();//forecast是一个数组,里面有今天和之后的几天的数据
            //今天的
            jsonObject = forecast.at(0).toObject();//数组第0个看成一个obj对象,第0个就是今天
            jsonData = jsonObject.value("low").toString().mid(3,2)+"/";
            jsonData = jsonData+jsonObject.value("high").toString().mid(3,2);
            ui->temperature2->setText(jsonData);
            jsonData = jsonObject.value("type").toString();
            ui->weather5->setText(jsonData);

            for (int i=0;i<12;++i) {
                if(jsonData == iconList[i]){
                    iconPic = ":/"+QString::number(i+1)+".png";
                    qDebug("%s",iconPic.toStdString().data());
                    break;
                }
                if(i == 11){
                    qDebug("未找到对应的图片");
                    iconPic = ":/"+QString::number(13)+".png";//若找不到就显示第13张设置好的图片
                }
            }
            QPixmap iconPix2(iconPic);
            iconPix2 = iconPix2.scaled(ui->weather2->width(),ui->weather2->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
            ui->weather2->setPixmap(iconPix2);

            //明天的
            jsonObject = forecast.at(1).toObject();//数组第0个看成一个obj对象,第0个就是今天
            jsonData = jsonObject.value("low").toString().mid(3,2)+"/";
            jsonData = jsonData+jsonObject.value("high").toString().mid(3,2);
            ui->temperature3->setText(jsonData);
            jsonData = jsonObject.value("type").toString();
            ui->weather6->setText(jsonData);

            for (int i=0;i<12;++i) {
                if(jsonData == iconList[i]){
                    iconPic = ":/"+QString::number(i+1)+".png";
                    qDebug("%s",iconPic.toStdString().data());
                    break;
                }
                if(i == 11){
                    qDebug("未找到对应的图片");
                    iconPic = ":/"+QString::number(13)+".png";//若找不到就显示第13张设置好的图片
                }
            }
            QPixmap iconPix3(iconPic);
            iconPix3 = iconPix3.scaled(ui->weather3->width(),ui->weather3->height(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
            ui->weather3->setPixmap(iconPix3);

        }
    }

}

void Widget::iconPath()
{
    //和图片的顺序一一对应
    iconList << "中雨"
             << "冰雹"
             << "多云"
             << "大雨"
             << "大雪"
             << "小雨"
             << "晴"
             << "暴雨"
             << "沙尘"
             << "雷雨"
             << "小雨转多云"
             << "雾霾";
}

运行到开发板结果:

        开发板要先有网络

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值