前言
在项目过程中要做一个图片分享功能,将图片上传到服务器 然后服务器返回图片的存储位置,本地将路径生成二维码进行分享,这里要讲的是图片上传部分,我采用的是post方式上传,要用到Qt的QNetworkAccessManager类,其实实现很简单,可以拓展为上传键值对或者其他到服务器,原理都一样的。
正文
废话不多说,直接上代码
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
class ALPostFile : public QObject
{
Q_OBJECT
public:
ALPostFile();
~ALPostFile();
Q_INVOKABLE void setServerAddr(QString addr){m_strServerAddr = addr;}
Q_INVOKABLE void setPostFilePath(QString filePath){m_strFilePath = filePath;this->start();}
void start();
signals:
void sigReplyMessage(int retCode,QString msg);//从服务器返回的数据,retCode=0 表示成功,那么msg就是图片的存储位置;retCode非0 msg就是错误信息
private slots:
void replyFinished(QNetworkReply *reply);
private:
QString m_strServerAddr = "";
QString m_strFilePath = "";
QNetworkAccessManager * m_pNetWorkManager = NULL;
};
这里我封装来一个类,专门管理图片上传并且处理服务器返回的信息,服务器返回的是json格式的数据,具体格式可以和服务器端自行商量。由于这个类中的接口还要用于QML端调用,所以接口定义的时候加了Q_INVOKABLE,不了解的可以去查询相关介绍,这里不再多说。
来看看源文件
#include "alpostfile.h"
#include <QUrlQuery>
#include <QFile>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>
ALPostFile::ALPostFile()
{
m_pNetWorkManager = new QNetworkAccessManager();
connect(m_pNetWorkManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*)));
}
ALPostFile::~ALPostFile()
{
delete m_pNetWorkManager;
}
void ALPostFile::start()
{
if(m_strFilePath.isEmpty() || m_strServerAddr.isEmpty()){
return;
}
QFile file(m_strFilePath);
if (!file.open(QIODevice::ReadOnly)||file.size()==0)
{
file.close();
return ;
}
QByteArray fdata = file.readAll();
if(fdata.isEmpty()){
return;
}
file.close();
QUrlQuery params;
params.addQueryItem("file",fdata.toBase64());
QNetworkRequest request;
QString data = params.toString();
request.setUrl(m_strServerAddr);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded;charset=utf-8");
request.setHeader(QNetworkRequest::ContentLengthHeader, data.size());
m_pNetWorkManager->post(request, params.toString().toUtf8());
}
void ALPostFile::replyFinished(QNetworkReply *reply)
{
QByteArray ba = reply->readAll();
QJsonParseError jsonpe;
QJsonDocument json = QJsonDocument::fromJson(ba, &jsonpe);
if (jsonpe.error == QJsonParseError::NoError)
{
if (json.isObject())
{
QJsonObject obj = json.object();
if (obj.contains("error_code"))
{
if(obj["error_code"] == 0){//成功
if(obj.contains("url")){
qDebug() << "obj[url] = " << obj["url"].toString();
emit sigReplyMessage(0,obj["url"].toString());
}
}
else{
if(obj.contains("message")){
qDebug() << "obj[message] = " << obj["message"];
emit sigReplyMessage(1,obj["message"].toString());
}
}
}
}
else
{
qDebug() << "error, shoud json object";
}
}
else
{
qDebug() << "error:" << jsonpe.errorString();
}
}
代码很简单,实例化该类后,先要调用setServerAddr来设置服务器的地址,然后调用setPostFilePath来设置上传文件的位置,最后调用start接口开始上传,若服务器有返回数据,那么会进入到replyFinished中处理。代码结构很清晰,不再赘述。