QT练手小项目-——天气播报小狗(ui展示分析,构造实现,json格式数据分析,界面交互,天气图标处理,小狗语音)

本文介绍了一个基于QT的桌面天气应用程序的开发过程。该应用利用JSON格式的天气API接口获取实时天气信息,并通过自定义UI展示天气详情。文章还详细解释了如何解析JSON数据、实现界面跳转以及使用语音播报功能。
摘要由CSDN通过智能技术生成

前言

        经过之前一段时间的QT学习,做出一个小软件来总结自己掌握关于qt的知识点。网络上有许多免费的天气接口(api),有xml格式的,也有json格式的。具体xml和json有什么区别,这里我就不去深究了,我们这里用的是一个json格式的数据,所以重点是对json格式的数据进行处理

 效果的展示

         颜面是很重要的,首先介绍我的ui

然后介绍ui上各个按键的功能

 

“1”:这是小狗按钮,点击此键,跳转出一个小狗界面

tips:点击小狗即可实现播报出今天的天气内容,以及温馨提醒。

“2”:实时温度

“3”:现在的天气图片状态

“4”:现在的天气文字状态

“5”:具体今天的温度范围

“6”:刷新界面,然后访问api接口

“7”:定位选择的城市

构造实现

        把 ui 和 网络请求解析 分开,ui 是主线程,网络的请求解析是一个单独的线程,net_thread.cpp是线程的文件,将weather.cpp类移入到线程中运行,这样在解析数据的时候,如果数据过大,不至于会影响到 ui 的响应。
把所有的图片都加到了资源里,资源里还有一个包含了所有城市ID的.json文件(这是在网上不知道哪个不知名大佬总结的,在获取天气信息之前,需要先将 .json 里的城市ID读取出来,在拼凑成一个完整的 url 。

#ifndef NET_THREAD_H
#define NET_THREAD_H

#include <QObject>
#include <QThread>

#include <class_weather/weather.h>

class NET_THREAD : public QObject
{
    Q_OBJECT
signals:
    void thread(QString);
public:
    explicit NET_THREAD(QObject *parent = nullptr);
    ~NET_THREAD();

    QThread * qThread = nullptr;

    WEATHER * weather = nullptr;

    void startThread();

    void stopThread();

signals:

};

#endif // NET_THREAD_H

api接口函数,json数据的分段

        

http://t.weather.sojson.com/api/weather/city/城市ID

连接api之后,返回的数值如图所示:

 那我们该如何对返回的数据进行分段处理呢?

   这里借鉴了csdn上大佬的处理方法

        数据的分段:

        

JSON返回示例 :
{
errNum: 0,
errMsg: "success",
retData: {
   city: "北京", //城市
   pinyin: "beijing", //城市拼音
   citycode: "101010100",  //城市编码   
   date: "15-02-11", //日期
   time: "11:00", //发布时间
   postCode: "100000", //邮编
   longitude: 116.391, //经度
   latitude: 39.904, //维度
   altitude: "33", //海拔 
   weather: "晴",  //天气情况
   temp: "10", //气温
   l_tmp: "-4", //最低气温
   h_tmp: "10", //最高气温
   WD: "无持续风向",  //风向
   WS: "微风(<10m/h)", //风力
   sunrise: "07:12", //日出时间
   sunset: "17:44" //日落时间
  }    
}
备注 :
请将apikey作为参数添加到header中;
当返回{"errNum":300003,"errMsg":"url is not parse"} 时,请校验是否传入apikey;

为了取到其中的各条信息需要用到JSON数据的解析

$cityname = urlencode($_POST['cityname']);
            //设置天气API的url地址,初始化cURL 根据城市名称查询
            $url = 'http://apis.baidu.com/apistore/weatherservice/cityname?cityname='.$cityname; //天气API
            //$this->display();
            $ch = curl_init();
            $header = array(
                'apikey: e858d877f6febd23d6623e14a3dbf220',
            );
            //设置cURL的相关参数,执行HTTP请求
            curl_setopt($ch,CURLOPT_URL,$url);
            // 添加apikey到header
            curl_setopt($ch, CURLOPT_HTTPHEADER  , $header);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
            //采集数据
            $output = curl_exec($ch);
            //关闭
            curl_close($ch);
            $res = json_decode($output,true);   //将生成的结果转化为json数据
            $this->assign('city',$res["retData"]['city']);
            $this->assign('date',$res["retData"]['date']);
            $this->assign('time',$res["retData"]['time']);
            $this->assign('temp',$res["retData"]['temp']);
            $this->assign('l_tmp',$res["retData"]['l_tmp']);
            $this->assign('h_tmp',$res["retData"]['h_tmp']);
            $this->assign('weather',$res["retData"]['weather']);
            $this->assign('WS',$res["retData"]['WS']);
            $this->display();

通过这种方式就可以获取其中的每条信息。这种方式基本可以处理所有API返回数据。

$city = $res["resData"]["city"];

分段之后我们用文本的方式记录下来:

关于界面跳转问题

         

 当我们点击地点查询,和小狗这两个按钮,我们的主界面会消失然后分别出现

小狗:

 地点查询:

 关于界面的跳转,我都是运用信号与槽的方式来实现的。

 具体代码:

 

 思路:

        拿小狗界面举例,首先我用hide隐藏小狗这个界面,当我点击小狗这个按钮的时候,实现小狗显示,然后在小狗的类里实现主界面的消失隐藏,形成一种交互过程,实现了点击按钮,一个消失一个出现。

天气图标实现 

          在网上找到了很多关于天气打包好的图片:

  

然后把这些图片添加到资源,例如:

 然后每个图片通过比较字符串判断是什么天气,例如:

如果是小雨,则会去找到小雨天气的图片的路径并且显示出来:

代码实现

 if(info->forecast[0].weatherType.contains("多云"))
    {
        pixmap = ":/icons/weather_icons/duoyun.png";
    }
    else if(info->forecast[0].weatherType.contains("晴"))
    {
        pixmap = ":/icons/weather_icons/qing.png";
    }
    else if(info->forecast[0].weatherType.contains("小雨"))
    {
        pixmap = ":/icons/weather_icons/xiaoyu.png";
    }
    else if(info->forecast[0].weatherType.contains("沙尘"))
    {
        pixmap = ":/icons/weather_icons/shachen.png";
    }
    else if(info->forecast[0].weatherType.contains("雾霾"))
    {
        pixmap = ":/icons/weather_icons/wumai.png";
    }
    else if(info->forecast[0].weatherType.contains("雪转晴"))
    {
        pixmap = ":/icons/weather_icons/xuezhuanqing.png";
    }
    else if(info->forecast[0].weatherType.contains("夜多云"))
    {
        pixmap = ":/icons/weather_icons/yeduoyun.png";
    }
    else if(info->forecast[0].weatherType.contains("中雨"))
    {
        pixmap = ":/icons/weather_icons/zhongyu.png";
    }
    else if(info->forecast[0].weatherType.contains("暴雨"))
    {
        pixmap = ":/icons/weather_icons/baoyu.png";
    }
    else if(info->forecast[0].weatherType.contains("冰雹"))
    {
        pixmap = ":/icons/weather_icons/bingbao.png";
    }
    else if(info->forecast[0].weatherType.contains("大雪"))
    {
        pixmap = ":/icons/weather_icons/daxue.png";
    }
    else if(info->forecast[0].weatherType.contains("大雨"))
    {
        pixmap = ":/icons/weather_icons/dayu.png";
    }
    else if(info->forecast[0].weatherType.contains("雷雨"))
    {
        pixmap = ":/icons/weather_icons/leiyu.png";
    }

    ui->label_weather_icon->setPixmap(QPixmap(pixmap));
}

小狗语音播报 

当我们点击小狗,小狗就会自动播报处今天的天气情况,以及提醒。我是这样实现的:

        因为,天气的数据处理和小狗不是同一个类,所以我决定在天气数据的类里创建一个文本文件,然后经过字符格式的转换写入文件,然后进行文本的换行处理,在狗的类里在根据路径打开文本文件并朗读,使语音有分段。

具体代码

天气类里实现的部分

  QFile file("qwer.txt");
    char *zxc="\n";
    file.open(QIODevice::WriteOnly);
     file.write(info->cityName.toUtf8());

    char* zaxc="今日实时温度";

    file.write(zxc);
    file.write(zaxc);

    file.write(info->realTime.temp.toUtf8());
file.write(zxc);
    file.write(info->forecast[0].temp.toUtf8());
    file.write(zxc);
     file.write(info->forecast[0].weatherType.toUtf8());
     file.write(zxc);


    for(int i=0;i<4;i++)
    {
    QString str=showMessageList[i];
    QByteArray buf =str.toUtf8();
    file.write(buf);
    file.write(zxc);
    }


    file.close();

小狗类里实现的部分


        QTextToSpeech *s = new QTextToSpeech;
        QFile file("qwer.txt");
        file.open(QIODevice::ReadOnly);
        QByteArray zbc;
        zbc=file.readAll();
        s->say(zbc);
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞赴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值