Qt学习笔记——网络数据获取QNetworkAccessManager与QNetworkReply

一般的,一个程序中只需要用到一个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信号,用于managerfinished信号连接

#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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值