json
理论
什么是JSON?
规则
被大括号包括的是JSON对象,被中括号包括的是JSON数组.
JSON数组JSON对象
实验
构建JSON
用代码实现如下json内容:
//构建JSON
void WirteJson()
{QJsonObject rootObject;//1.插入name字段rootObject.insert("name","china");//2.插入info字段QJsonObject infoObj;infoObj.insert("capital","beijing");infoObj.insert("asian",true);infoObj.insert("founded",1949);rootObject.insert("info",infoObj);//3.插入省份字段QJsonObject provinsSD;provinsSD.insert("name","shandong");provinsSD.insert("capital","jinan");QJsonObject provinsZJ;provinsZJ.insert("name","zhejiang");provinsZJ.insert("capital","hangzhou");QJsonArray provinArray;provinArray.append(provinsSD);provinArray.append(provinsZJ);rootObject.insert("provinces",provinArray);//4.将rootObj转换为json字符串QJsonDocument doc(rootObject);QByteArray json=doc.toJson();//5.打印输出qDebug()<<QString(json).toUtf8().data();//6.将json字符串写入到文件QFile file("D:\\QTproject\\JSON.json");file.open(QFile::WriteOnly);file.write(json);file.close();
}
解析JSON
//解析json字符串
void JsonFrom()
{//1.读取文件QFile file("D:\\QTproject\\JSON.json");file.open(QFile::ReadOnly);QByteArray json=file.readAll();file.close();//获取一下json源QJsonDocument doc=QJsonDocument::fromJson(json);if(!doc.isObject()){qDebug()<<"not is a JSONObject!";return;}//name字段QJsonObject obj=doc.object();QStringList Keys=obj.keys();for(int i=0;i<Keys.size();i++){//获取key-valueQString key=Keys[i];QJsonValue value=obj.value(key);if(value.isBool()){qDebug()<<key<<":"<<value.toBool();}else if(value.isString()){qDebug()<<key<<":"<<value.toString();}else if(value.isDouble()){qDebug()<<key<<":"<<value.toInt();}//info字段else if(value.isObject()){qDebug()<<key<<":";QJsonObject infoObj=value.toObject();QString capital=infoObj["capital"].toString();bool asian=infoObj["asian"].toBool();int founded=infoObj["founded"].toInt();qDebug()<<"capital"<<" : "<<capital;qDebug()<<"asian"<<" : "<<asian;qDebug()<<"founded"<<" : "<<founded;}//省份字段else if(value.isArray()){qDebug()<<key<<":";QJsonArray provinceArray=value.toArray();for(int i=0;i<provinceArray.size();i++){QJsonObject provinceObj=provinceArray[i].toObject();QString name=provinceObj["name"].toString();QString capital=provinceObj["capital"].toString();qDebug()<<"name"<<" : "<<name;qDebug()<<"capital"<< " : "<<capital;}}}
}
HTTP
HTTP理论
布局
代码实现
取消主界面自带边框
setWindowFlag(Qt::FramelessWindowHint); //设置窗口无边框setFixedSize(width(),height()); //设置窗口固定大小
设置右键弹出退出按钮
mExitAct->setText("退出");mExitAct->setIcon(QIcon(":/res/close.ico"));mExitMenu->addAction(mExitAct); //将我们的行为添加到出菜单里
响应鼠标事件
//弹出右键菜单
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{mExitMenu->exec(QCursor::pos()); //传送鼠标位置
}
绑定信号槽
connect(mExitAct,QAction::triggered,this,[=]{qApp->exit(0);});
去掉了系统自带的标题栏就无法拖动窗口了,我们需要自己实现通过鼠标拖动窗口的功能.
实现自定义拖动窗体功能
定义一个变量
QPoint mOffset; //鼠标离左上角的距离
定义两个方法
//处理鼠标点击事件 void mousePressEvent(QMouseEvent *event);//处理鼠标移动事件void mouseMoveEvent(QMouseEvent *event);
方法实现
//处理鼠标点击事件
void MainWindow::mousePressEvent(QMouseEvent *event)
{mOffset = event->globalPos() - this->pos();
}//处理鼠标移动事件
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{this->move(event->globalPos() - mOffset);
}当鼠标点击时会调
用mousePressEvent()函数,获取鼠标点击的位置,当鼠标按住移动的时候会调用 mouseMoveEvent()函数,会用鼠标当前位置减去左上角位置就是移动的位置.从而实现拖动窗体的效果.
利用网络获取天气
声明一个 QNetworkAccessManager类型的对象:
QNetworkAccessManager *mNetAccessManager;
把 mNetAccessManager对象创建出来:
mNetAccessManager =new QNetworkAccessManager(this);
关联信号槽
将mNetworkAccessManager的finish信号,与自定义的onReplied槽函数进行关联:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
mNetAccessManager =new QNetworkAccessManager(this);
connect(mNetAccessManager,&QNetworkAccessManager::finished,this,&MainWindow::onReplied);
getWeatherInfo("101010100");
}
发送http请求
在mainwindow.h文件里声明一个getWeatherInfo()函数用来发送http的成员函数:
class MainWindow : public QMainWindow
{
protected:void getWeatherInfo(QString citycode);
}
调用getWeatherInfo()函数来从网络中获取天气:
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
//请求北京的天气
getWeatherInfo("101010100"); //北京的城市码
}
//通过输入一个城市的代码获取这个城市的天气
void MainWindow::getWeatherInfo(QString citycode)
{QUrl url("http://t.weather.itboy.net/api/weather/city/101010100"+citycode);mNetAccessManager->get(QNetworkRequest(url));
}
接收服务端数据
当http请求完毕,返回数据的时候,mNetAccessManager就会发射一个finished信号, 进而调用onReplied()槽函数.
定义onReplied()函数:
void MainWindow::onReplied(QNetworkReply *reply)
{qDebug()<<"onReplied success";int status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
}
此时响应头,状态码,响应体,城市码,这些都在reply里存着.我们可以将这些信息打印出来看看:
void MainWindow::onReplied(QNetworkReply *reply)
{qDebug()<<"onReplied success";int status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();qDebug()<<"operation: "<<reply->operation();qDebug()<<"status code: "<<status_code;qDebug()<<"url: "<<reply->url();qDebug()<<"raw header: "<<reply->rawHeaderList();
}
增强代码健壮性:
void MainWindow::onReplied(QNetworkReply *reply)
{qDebug()<<"onReplied success";int status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();if(reply->error()!=QNetworkReply::NoError||status_code!=200){qDebug()<<reply->errorString().toLatin1().data();QMessageBox::warning(this,"天气","请求数据失败",QMessageBox::Ok);}else{QByteArray byteArray = reply->readAll();qDebug()<<"read all: "<<byteArray.data();}reply->deleteLater();
}
至此我们已经可以获取出北京市的天气了:
我们把这些数据放到json解析器就可以看的比较清楚: