前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt开源网络库[5]-lambda支持

Qt开源网络库[5]-lambda支持

作者头像
Qt君
发布2019-07-15 15:33:39
9190
发布2019-07-15 15:33:39
举报
文章被收录于专栏:跟Qt君学编程跟Qt君学编程

在不断使用该库的过程中会遇到这样的一个问题,比如错误提示我只需要打印到终端就可以了,每一次的请求都需要定义一个槽函数然后等待异步调用.在这个过程中,需要定义一个槽函数就会略显得有些繁琐了.

Lambda表达式的支持就是为了解决这类问题,但是事物都有两面性,lambda的支持在使用的方便同时也会增加使用的复杂性.有关与lambda的介绍,可以查看历史文章"这是一个函数[](){}"了解.

1. 使用Lambda的简化对比

代码语言:javascript
复制
m_service.get("https://www.qt.io")
         .onResopnse([](QByteArray result){ qDebug()<<"Result: "<<result; })
         .onResopnse([](qint64 recv, qint64 total){ qDebug()<<"Total: "<<total<<"; Received: "<<recv; })
         .onError([](QString errorStr){ qDebug()<<"Error: "<<errorStr; })
         .exec();

m_service.get("https://www.qt.io")
         .onResponse(this, SLOT(finish(QByteArray)))
         .onResponse(this, SLOT(downloadProgress(qint64,qint64)))
         .onError(this, SLOT(error(QString)))
         .exec();

对比lambda表达式的网络请求

(1) 两条请求的作用是一样的,写法不一样。第一个请求的写法是lambda表达式的写法,而第二个请求的写法则是通过绑定信号与槽的写法,但它需要创建槽函数,使用起来会繁琐一点;

(2) 使用lambda方式会大大简化代码,避免繁琐操作.

2. 接口的变化

(1) 在HttpRequest类对外新增以下接口:

代码语言:javascript
复制
HttpRequest &onResopnse(std::function<void (QNetworkReply*)> lambda);
HttpRequest &onResopnse(std::function<void (QVariantMap)> lambda);
HttpRequest &onResopnse(std::function<void (QByteArray)> lambda);
HttpRequest &onResopnse(std::function<void (qint64, qint64)> lambda);
HttpRequest &onError(std::function<void (QNetworkReply::NetworkError)> lambda);
HttpRequest &onError(std::function<void (QString)> lambda);
HttpRequest &onError(std::function<void (QNetworkReply::NetworkError, QNetworkReply*)> lambda);
HttpRequest &onError(std::function<void (QString, QNetworkReply*)> lambda);

(2) 使用std::function的形式来支持对应的执行操作;

3. Lambda注册

(1) 通过提前注册类型到元对象系统,利用元对象系统的QVariant将std::function模板保存起来;

代码语言:javascript
复制
Q_DECLARE_METATYPE(std::function<void (QNetworkReply*)>);
Q_DECLARE_METATYPE(std::function<void (QByteArray)>);
Q_DECLARE_METATYPE(std::function<void (QVariantMap)>);

Q_DECLARE_METATYPE(std::function<void (QString)>);
Q_DECLARE_METATYPE(std::function<void (QNetworkReply::NetworkError)>);
Q_DECLARE_METATYPE(std::function<void (QNetworkReply::NetworkError, QNetworkReply *)>);
Q_DECLARE_METATYPE(std::function<void (QString, QNetworkReply *)>);

Q_DECLARE_METATYPE(std::function<void (qint64, qint64)>);

(2) 通过增加methodParams的"lambda"字段属性,用来判断其执行的方法.

代码语言:javascript
复制
static const QMap<QString, QMap<QString, QVariant>> methodParams =
{
    {
        N2S(HttpResponse::onResponse_QNetworkReply_A_Pointer),
        {
            {"types", QStringList({T2S(QNetworkReply*)})},
            {"lambda", T2S(std::function<void (QNetworkReply*)>)},
            {"signal", SIGNAL(finished(QNetworkReply*))},
            {"isAutoInfer", true}
        }
    },
...

4. 源代码:

想深入了解该库,可以查看源代码学习,查看历史文章或和作者沟通了解该库的介绍原理,相信会对你的网络编程有所帮助.

(1) 源码地址(不定期更新):

代码语言:javascript
复制
https://github.com/aeagean/QtNetworkService

(2) 使用该库的应用:

代码语言:javascript
复制
https://github.com/aeagean/QtKugouApi
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档