Hi, might help, this won’t answer you question directly but might give some 
helper idea to ease the pain. What we did is a wrapper around 
QNetworkAccessManager class call RequestManager that own a QNetworkManager. It 
expose the following methods:

QNetworkReply* postRequest(QNetworkRequest& request, const QByteArray& payload);
// Do the same for put, update, get…

And signal slots:
signals:
    void replySuccess(QNetworkReply* reply);
    void replyError(QNetworkReply* reply);

public slots:
    void handleFinished(QNetworkReply *networkReply);

It manage the return code immediate and signal then valide the answer is a 
success or a failure. You can store the context or object into a map with your 
request, the reply will have the request into it so you can load back the 
needed information when you receive the replySuccess or reply Error signals 
back.  Make some helper to convert you payload to QByteArray so you can use it 
with json, text, etc…

I also made some ScopeAction class so my NetworkAccess manager reply handler 
can make sure the delete later is not forgetten:

connect(&network_manager, &QNetworkAccessManager::finished, this, 
&RequestManager::handleFinished);


void RequestManager::handleFinished(QNetworkReply *networkReply)
{
    ScopeAction action_delete([&](){ networkReply->deleteLater(); });
… // process the reply error or success here and emit either the replySuccess 
or replyError signal here, this need to be non queued connection to avoid bad 
object access.
}

This helped me a lot to clean my network management for upper layer. So I can 
simply connect to the reply success or replyError and with the request pointer 
form the reply you can load the associated data and continue form that point 
easily.

The async/await would be nice, but I’m not sure this would play well with the 
Qt event loop and the object memory management. They are also super hard to 
debug the call stack is lost.

Jérôme Godbout, B. Ing.

Software / Firmware Team Lead
O: (418) 682-3636 ext.: 114
C: (581) 777-0050
godbo...@dimonoff.com<mailto:godbo...@dimonoff.com>
[signature_182238435]<https://www.dimonoff.com/>
dimonoff.com<https://www.dimonoff.com/>
1015 Avenue Wilfrid-Pelletier,
Québec, QC G1W 0C4, 4e étage


From: Interest <interest-boun...@qt-project.org> on behalf of Jason H 
<jh...@gmx.com>
Date: Wednesday, June 2, 2021 at 10:41 AM
To: interestqt-project.org <interest@qt-project.org>
Subject: [Interest] QNetworkReply lambdas?
I'm trying to figure out a more flexible way to do QNetworkReply. Ideally this 
would be through some async/await but I don't think Qt is "there" yet. (C++20 
defines async/await, but there is not a library yet, and even Qt6 doesn't 
target C++20). So the callback lambda handler looks like the best option for 
now.

I have a QObject derived class, with a post() function. It takes an endpoint, 
and object (to be converted to JSON) and a lambda. Example:
remoteCloud->post("/login", credentials, [=](QNetworkReply* reply){
        if (reply->error() == QNetworkReply::NoError) {
                update("cartridge",
                           {{"synced", QDateTime::currentDateTime()}},
                           {{"cartridgeId", map["cartridgeId"]}});
        }
        reply->deleteLater();
});

With an implementation of:
template<typename F>
QNetworkReply *RemoteCloud::post(const QString& endpoint, const QVariantMap& 
item, F &lambda) {
        QNetworkReply* reply = m_nam.post(QNetworkRequest(endpoint), 
JSON(item));
        connect(reply, &QNetworkReply::finished, lambda);
        return reply;
}


Note that a lot of the Qt examples use a connect statement like this:
connect(reply, &QNetworkReply::finished, [request, reply](){ ... });

But when I tried to set this up, I either got static assert errors or l-value 
errors.

However I am trying to go one better and have my RemoteCloud::post set up the 
connect with the lambda. Is this possible?

_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest
_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to