最近笔者想用Qt来实现一个简单的天气预报功能,虽然现在早已流行使用Qt5以上版本来做设计并且网络上也有非常多基于Qt5来实现天气预报的案例,但是对于很多初学者依然会使用Qt4来学习,因此笔者来分享一个基于Qt4实现的案例,希望对大家有所帮助。
当我们通过网络使用中国天气网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
截取的长度
由于reply->readAll();
返回的字符串为QByteArray类型,需将QByteArray转化为QString,否则出现乱码问题。这边笔者参考了很多网上的QByteArray转QString的方式,都无法起到作用,因此尝试使用间接转换的方法:将QByteArray
转char *
,再将char *
转QString
,解决问题。笔者有一篇 Qt4-const char*转QString.的文章可供参考。
{"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);
}
}
参考:
https://blog.csdn.net/qq_36583051/article/details/78784706
https://www.cnblogs.com/ACPIE-liusiqi/p/10629306.html