基于Qt4的天气预报

基于Qt4的天气预报

前言

最近笔者想用Qt来实现一个简单的天气预报功能,虽然现在早已流行使用Qt5以上版本来做设计并且网络上也有非常多基于Qt5来实现天气预报的案例,但是对于很多初学者依然会使用Qt4来学习,因此笔者来分享一个基于Qt4实现的案例,希望对大家有所帮助。

一、效果展示

基于Qt4的天气预报_第1张图片

二、遇到的几个问题

2.1 Json数据解析

当我们通过网络使用中国天气网API接口:http://wthrcdn.etouch.cn/weather_mini?获取某地的天气信息时,获取成功后服务器返回的是一串Json数据,如下:

"{"data":{"yesterday":
   {"date":"9日星期一","high":"高温 24℃","fx":"南风","low":"低温 16℃","fl":"","type":"多云"},"city":"厦门",
    "forecast":[
      {"date":"10日星期二","high":"高温 22℃","fengli":"","low":"低温 14℃","fengxiang":"东北风","type":"多云"},
      {"date":"11日星期三","high":"高温 21℃","fengli":"","low":"低温 14℃","fengxiang":"东风","type":"晴"},
      {"date":"12日星期四","high":"高温 17℃","fengli":"","low":"低温 14℃","fengxiang":"无持续风向","type":"阴"},
      {"date":"13日星期五","high":"高温 24℃","fengli":"","low":"低温 16℃","fengxiang":"东风","type":"阴"},
      {"date":"14日星期六","high":"高温 19℃","fengli":"","low":"低温 13℃","fengxiang":"东北风","type":"多云"}],
"ganmao":"将有一次强降温过程,且风力较强,极易发生感冒,请特别注意增加衣服保暖防寒。","wendu":"22"},"status":1000,"desc":"OK"}" 

因此,这样的数据我们不能直接使用,需要对其进行解析。而Qt4是没有JSon数据解析库的,很多人会说我们可以使用第三方库的方式来加入JSon数据解析相关库进行解析呀,是的没错,不过笔者这边要介绍的是另外一种简单的方式(使用QString中的两个方法):

方法一

QString QString::section ( QChar sep, int start, int end = -1, SectionFlags flags = SectionDefault ) const

QString::section 用来以某个字符切割字符串

参数说明:

sep表示用来切割的字符,
start表示开始切割的位置,
end表示切割的结束位置,
flag参数可以用来影响函数的行为的某些方面,例如是否区分大小写,是否跳过空字段和如何处理前导和尾随分隔符。
结果返回开始切割那个字符到结束切割的那个字符之后的那个字符串

方法二

QString QString::mid ( int position, int n = -1 ) const

QString::mid 用来获取指定位置子串

参数说明:

position截取的开始位置
n截取的长度

***************** 具体使用参考文末的源码展示 ********************

2.2数据显示出现乱码

由于reply->readAll();返回的字符串为QByteArray类型,需将QByteArray转化为QString,否则出现乱码问题。这边笔者参考了很多网上的QByteArray转QString的方式,都无法起到作用,因此尝试使用间接转换的方法:将QByteArraychar *,再将char *QString,解决问题。笔者有一篇 Qt4-const char*转QString.的文章可供参考。

***************** 具体使用参考文末的源码展示 ********************

2.3返回的Json数据不是天气信息

{"status":1002,"desc":"invilad-citykey"}" 

这边表示数据申请时城市名称有问题,正确格式:http://wthrcdn.etouch.cn/weather_mini?city=厦门

三、源码

//.pro文件
#-------------------------------------------------
#
# Project created by QtCreator 2020-03-09T14:51:30
#
#-------------------------------------------------

QT       += core gui network

TARGET = 07_weatherTest
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

//main.c 文件
#include 
#include "widget.h"
#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //设置本地编码
    QTextCodec *codec = QTextCodec::codecForLocale();
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);

    Widget w;
    w.show();

    return a.exec();
}

//widget.h文件
#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace Ui {
    class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

public slots:
    void replyFinished(QNetworkReply *reply);

private slots:
    void on_pBtn_find_clicked();

private:
    Ui::Widget *ui;
    QString all;
    QByteArray bytes;
    QString currentWT;
    QNetworkAccessManager *manage;

    void setWeatherInfo(int index, QGroupBox *gBox_date, QLabel *lab_wd, QLabel *lab_fl, QLabel *lab_fx, QLabel *lab_tq);
    bool errorJudge();


};

#endif // WIDGET_H

//widget.c文件
#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    manage = new QNetworkAccessManager(this);
    //信号槽绑定
    connect(manage, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}

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

void Widget::on_pBtn_find_clicked()
{
    QNetworkRequest network_request;
    //设置发送数据
    QString address = "http://wthrcdn.etouch.cn/weather_mini?city=";
    QString city = ui->lEdit_city->text();
    QString total = address + city;
    network_request.setUrl(QUrl(total));
    manage->get(network_request);
}

void Widget::replyFinished(QNetworkReply *reply)
{
    if(reply->error() == QNetworkReply::NoError)
    {
        //需将QByteArray转化为QString,否则出现乱码问题
        bytes = reply->readAll();
        const char * ch = bytes.data();
        all = QString::fromUtf8(ch);
        qDebug()<< all;
        if (errorJudge())
        {
            setWeatherInfo(4,ui->gBox1, ui->label_1wd, ui->label_1fl, ui->label_1fx, ui->label_1tq);
            setWeatherInfo(5,ui->gBox2, ui->label_2wd, ui->label_2fl, ui->label_2fx, ui->label_2tq);
            setWeatherInfo(6,ui->gBox3, ui->label_3wd, ui->label_3fl, ui->label_3fx, ui->label_3tq);
            setWeatherInfo(7,ui->gBox4, ui->label_4wd, ui->label_4fl, ui->label_4fx, ui->label_4tq);
            setWeatherInfo(8,ui->gBox5, ui->label_5wd, ui->label_5fl, ui->label_5fx, ui->label_5tq);
        }
        else
        {
            qDebug()<< "城市名称错误!!";
        }
    }
    else
    {
        qDebug()<< "网络出错!!";
    }
    reply->deleteLater();
}

bool Widget::errorJudge()
{
    int status;
    QString info;
    QString tmp;

    tmp = all.section(':',1);
    info = tmp.mid(0,4);
    status = info.toInt();
    if (status == 1002)
    {
        return false;
    }
    return true;
}

void Widget::setWeatherInfo(int index, QGroupBox *gBox_date, QLabel *lab_wd, QLabel *lab_fl, QLabel *lab_fx, QLabel *lab_tq)
{
    QString tmp;
    QString T,windPower;
    QString info;

    info = all.section('{',index);
    tmp = info.section('"',1,1);

    if(tmp == "date")
    {
        info = info.section(':',1);
        tmp = info.section('"',1,1);
        gBox_date->setTitle(tmp);

        info = info.section(':',1);
        tmp = info.section('"',1,1);
        T = tmp.mid(3) + "/";

        info = info.section(':',1);
        tmp = info.section('"',1,1);
        windPower = tmp.mid(9,4);
        lab_fl->setText(windPower);

        info = info.section(':',1);
        tmp = info.section('"',1,1);
        T += tmp.mid(3);
        lab_wd->setText(T);

        info = info.section(':',1);
        tmp = info.section('"',1,1);
        lab_fx->setText(tmp);

        info = info.section(':',1);
        tmp = info.section('"',1,1);
        currentWT = tmp;
        lab_tq->setText(currentWT);
    }
}

UI设计:
基于Qt4的天气预报_第2张图片

参考:
https://blog.csdn.net/qq_36583051/article/details/78784706
https://www.cnblogs.com/ACPIE-liusiqi/p/10629306.html

你可能感兴趣的:(Qt)