C++网络请求(get,post,上传图片)与QML混合编程
文章主要分两个大模块:C++模块和qml模块;包含了Qt下网络请求QNetworkAccessManager,QNetworkRequest,QNetworkReply类库,以及响应机制:信号与槽,同时还兼容了QML与C++信息的传递以及数据类型的转换;本人刚学QT不到一个月且第一次写文章给大家分享,如有不好的地方欢迎大家留言给出宝贵的意见。好了,啰嗦了半天,接着就看正文吧:
- get实现
- post实现
- 上传图片
- 获取网络返回结果并传递结果给qml
- qml与C++传递过程的数据转换
- qml使用C++网络类
get实现
这里两个参数其实分别是手机号码和请求接口名
RequestBaseStr_REGIST为宏定义请求接口地址
void CCNetWorkRequest::CCRequest_GET(QString param, QString interfaStr)
{
requestURL_Str = RequestBaseStr_REGIST;
requestURL_Str.append(interfaStr);
requestURL_Str.append(param);
qDebug()<<"req_url:"<<requestURL_Str;
//此处为返回给qml界面其所发出的请求信息(主要便于测试验证请求参数是否正确)
emit reqParamsReturn(requestURL_Str);
_netWorkRequest.setUrl(QUrl(requestURL_Str));
//通过manager直接调用get方法将request传递过去就可以了!
_netWorkManager->get(_netWorkRequest);
}
post实现
这里设计时第一个参数为qml传递过来的所需请求所有参数的json字符,第二个参数同上,接口名称
void CCNetWorkRequest::CCRequest_POST(QString param, QString interfaStr)
{
requestURL_Str = RequestBaseStr_REGIST;
requestURL_Str.append(interfaStr);
//这里主要将qml传递过来的json转换为请求data
transData = CCQmlStrToByteArray(param);
//校验传递的参数是否正确
if(transData.isNull())
{
emit reqErrorReturn("请求参数错误!");
return;
}
_netWorkRequest.setUrl(QUrl(requestURL_Str));
//设置请求头,必加
_netWorkRequest.setRawHeader("Content-Type","application/json;charset=UTF-8");
qDebug()<<"send data:"<<transData;
//请求前将所发请求信息返回qml界面显示(只为测试)
emit reqParamsReturn(requestURL_Str.append(transData));
_netWorkManager->post(_netWorkRequest,transData);
}
上传图片
void CCNetWorkRequest::CCRequest_UPLOAD(QString param, QString interfaStr, QString cPath)
{
requestURL_Str = RequestBaseStr_USER;
requestURL_Str.append(interfaStr);
//这里主要先将上传文件所带参数先转换为jsonobject为后面做准备
QJsonObject paramObject = CCQstringToJsonobject(param);
if(paramObject.isEmpty())
{
emit reqErrorReturn("图片请求参数错误!");
return;
}
// qDebug()<<"to_object_res:"<<paramObject;
//将文件通过base64转换为Qstring;
QString imageStr = CCImageToBass64(cPath);
qDebug()<<"ima:"<<imageStr;
if(imageStr==NULL)
{
emit reqErrorReturn("文件路径错误!");
return;
}
//将图片信息插入之前转换的jsonobject里面去完善整个请求参数
paramObject.insert("fileData",imageStr);
transData = QJsonDocument(paramObject).toJson();
_netWorkRequest.setUrl(QUrl(requestURL_Str));
_netWorkRequest.setRawHeader("Content-Type","application/json;charset=UTF-8");
// qDebug()<<"send data:"<<transData;
emit reqParamsReturn(requestURL_Str);
_netWorkReply = _netWorkManager->post(_netWorkRequest,transData);
connect(_netWorkReply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(CCRequest_UpLoadError(QNetworkReply::NetworkError)));
//建立网络请求信号槽
connect(_netWorkReply,SIGNAL(uploadProgress(qint64,qint64)),this,SLOT(CCRequest_OnUploadProgress(qint64,qint64)));
}
获取网络返回结果并传递结果给qml
//构造函数初始化时实例化manager,并建立finished对应信号与槽
_netWorkManager = new QNetworkAccessManager(this);
connect(_netWorkManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(CCRequest_Flished(QNetworkReply*)));
//接收网络请求返回完成结果,通过reply转换为string返回qml
void CCNetWorkRequest::CCRequest_Flished(QNetworkReply *rel)
{
QString rel_str;
if (rel->error())
{
rel_str = rel->errorString();
}
else
{
rel_str = rel->readAll();
}
//发送收到结果信号给qml (rel_str即为结果json值,具体的自己去转换)
emit reqFlishedReturn(rel_str);
qDebug()<<"flished rel:"<<rel_str;
}
//图片上传进度
void CCNetWorkRequest::CCRequest_OnUploadProgress(qint64 bytesSent, qint64 bytesTotal)
{
qDebug()<<"recive sent:"<<bytesSent<<"\n recive total:"<<bytesTotal;
}
void CCNetWorkRequest::CCRequest_UpLoadError(QNetworkReply::NetworkError errorCode)
{
qDebug()<<"recive error:"<<errorCode;
}
qml与C++传递过程的数据转换
将qml传递的参数转换为请求所需data,其他转换由于较多,这里就不写了,文章结尾会附上源码地址。
QByteArray CCNetWorkRequest::CCQmlStrToByteArray(QString qmlStr)
{
qDebug()<<"qmlStr :"<<qmlStr;
QJsonDocument jsonDocument = QJsonDocument::fromJson(qmlStr.toLocal8Bit().data());
if(jsonDocument.isNull())
{
qDebug()<<"===>"<<qmlStr.toLocal8Bit().data();
return NULL;
}
QByteArray byte_array = jsonDocument.toJson(QJsonDocument::Compact);
// QByteArray bytes = qmlStr.toLatin1(); QString转Qbyte
qDebug()<<"str to byte :"<<byte_array;
return byte_array;
}
qml使用C++网络类
#include <QGuiApplication>
#include <QQmlApplicationEngine>
//导入C++类库
#include "CCNetWorkRequest.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
//注册为qml可使用库
qmlRegisterType<CCNetWorkRequest>("zm.Net.CCRequest",1,0,"CCRequest");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
具体qml界面和导入qml系统库一样导入你注册的C++类库
import zm.Net.CCRequest 1.0
-----------------------------------------
//实例化网络请求类
CCRequest
{
id:ccRequest;
}
function getValidStr()
{
//设置请求验证码参数
var num = Math.floor(Math.random()*10000000+10000000);
var phone = "158"+num;
console.log("ran:"+phone);
var interfaStr = "register/getVerificationCode/"
ccRequest.setReqNum(1);
//直接调用c++类封装的get请求
ccRequest.CCRequest_GET(phone,interfaStr);
}
总结:
本文使用了几个关键点,一是网络请求相关操作,二,是信号与槽机制,三,是qml与c++混合编程。可能类似文章较多,在这里给大家说一声:献丑了,具体不明白的可下载源码查看;最后只说一点,对初学QT的同学,本文及源码绝对可以给你很大启发和知识,代码编写也绝对很规范。