一般的,一个程序中只需要用到一个QNetworkAccessManager实例,我们可以将它当作一个单例类来使用
当manager发出请求完毕时,会发出finished信号,并传递一个QNetworkReply的实例,网络请求的结果与返回的数据就存放在这个实例中,我们可以使用connect连接信号与槽,来对返回的数据进行操作
不作为单例类使用: 此处例子为获取网络图片
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished, [=](QNetworkReply * reply){
if(reply->error() == QNetworkReply::NoError){
QByteArray bytes = reply->readAll();
QPixmap pic;
pic.loadFromData(bytes);
//一个QLabel对象,用于显示获取到的图片或错误信息
imgLabel->setPixmap(pic);
}else{
imgLabel->setText(reply->errorString());
}
//reply需要我们自行delete掉,需使用deleteLater进行释放
reply->deleteLater();
});
manager->get(QNetworkRequest(QUrl("http://saqino.cn/smallpic/1.jpg")));
使用单例类: 最好是使用单例类,节省资源
由于我们在一个程序中可能不止用到一次请求,每次请求发出的finished信号都会进行响应,那么我们要怎么区分不同请求进行不同操作呢
使用一个QMap 容器 与一个枚举类型, 例如:
因为有两次请求,所以此处只是枚举了两种类型
enum RequestType{
imageType,
jsonType
};
QMap<QNetworkReply *, RequestType> typeMap;
每次进行数据获取,将返回的对象reply 与 枚举类型插入map中,用于区分操作:
此处的NetWorkUtil为单例类,通过静态函数获取对象,使用get函数发出请求
QNetworkReply * r_1 = NetWorkUtil::instance()->get("http://saqino.cn/smallpic/1.jpg");
typeMap.insert(r_1, imageType);
最后,是在槽函数中进行操作:
connect(NetWorkUtil::instance(), &NetWorkUtil::finished, this, &MainWidget::networkResult);
void MainWidget::networkResult(QNetworkReply *reply)
{
if(reply->error() != QNetworkReply::NoError){
qDebug() << reply->errorString();
return ;
}
RequestType reType = typeMap.value(reply);
switch (reType) {
case imageType:
{
图片请求的操作
}
break;
case jsonType:
{
json请求的操作
}
break;
}
//最后需要将reply释放
reply->deleteLater();
reply = nullptr;
}
单列类: 写一个类对manager进行封装
头文件
对拷贝构造函数与=赋值运行符进行Deleted操作,禁用这两个函数
写一个静态函数instance,用于获取当前类对象
写一个get方法,用于封装网络数据获取的get操作
实现一个内部友元类,将manager对象于内部类中实现
写一个finished信号,用于manager的finished信号连接
#include <QObject>
#include <QNetworkReply>
class NetWorkUtil : public QObject
{
Q_OBJECT
public:
static NetWorkUtil * instance();
QNetworkReply * get(const QString &url);
~NetWorkUtil();
signals:
void finished(QNetworkReply * reply);
public slots:
private:
explicit NetWorkUtil(QObject *parent = nullptr);
NetWorkUtil(NetWorkUtil &) = delete;
NetWorkUtil &operator=(NetWorkUtil nwu) = delete;
private:
class Private;
friend class Private;
Private * d;
};
cpp文件
#include "networkutil.h"
class NetWorkUtil::Private{
public:
Private(NetWorkUtil *q) :
manager(new QNetworkAccessManager(q))
{ }
QNetworkAccessManager * manager;
};
NetWorkUtil::NetWorkUtil(QObject *parent) : QObject(parent)
{
d = new NetWorkUtil::Private(this);
connect(d->manager, &QNetworkAccessManager::finished, this, &NetWorkUtil::finished);
}
QNetworkReply * NetWorkUtil::get(const QString &url)
{
return d->manager->get(QNetworkRequest(QUrl(url)));
}
NetWorkUtil *NetWorkUtil::instance()
{
static NetWorkUtil networkUtil;
return &networkUtil;
}
NetWorkUtil::~NetWorkUtil()
{
delete d;
d = nullptr;
}