lambda slots and QNetworkReply
-
I'm doing something wrong in this code:
void Packages::download(Package_t package) { _currentFilename = package.filename; _currentFile.setFileName(QString("/mnt/resources/packages/%1").arg(_currentFilename)); if (!_currentFile.open(QIODevice::WriteOnly)) { qWarning() << "Cannot open" << _currentFile.fileName(); return; } QUrlQuery query; query.addQueryItem("filename", package.filename); QUrl url(API_HOST + API_DOWNLOAD); url.setQuery(query); QNetworkRequest request(url); _managerDownload.setTransferTimeout(10000); QNetworkReply *reply = _managerDownload.get(request); connect(reply, &QNetworkReply::downloadProgress, [reply, this](qint64 bytesReceived, qint64 bytesTotal) { _currentFile.write(reply->readAll()); qInfo() << "progress" << bytesReceived << "/" << bytesTotal; }); connect(&_managerDownload, &QNetworkAccessManager::finished, [this](QNetworkReply *reply) { reply->deleteLater(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); qInfo() << "HTTP status:" << status << reply->url(); switch (status) { case 200: qInfo() << "Download completed successfully"; break; case 404: qInfo() << "File not found"; break; default: break; } _currentFile.close(); emit downloadFinished(status, _currentFilename); }); qInfo() << "GET request" << request.url(); }
Basically it should:
- open a local file where to store the downloaded binary data
- create the HTTP GET request
- bind the
downloadProgress
andfinished
signals to the two lambda functions
It works, but every time I call this function I see more and more messages, like it does not destroy the previous objects.
I don't get the mistake because:_managerDownload
is a class member, not a pointerreply
is deleted inside thefinished
slot
Can you help me to understand my fault please?
-
@Mark81 said in lambda slots and QNetworkReply:
connect(reply, &QNetworkReply::downloadProgress, [reply, this](qint64 bytesReceived, qint64 bytesTotal) { _currentFile.write(reply->readAll()); qInfo() << "progress" << bytesReceived << "/" << bytesTotal; });
You should do this once since there's no disconnect because you forgot to specify the receiver's object (third parameter): https://doc.qt.io/qt-5/qobject.html#connect-4 and https://doc.qt.io/qt-5/qobject.html#connect-5 --> set reply as context to make sure the slot gets disconnected or connect only once (which I would prefer)
-
@Mark81 said in lambda slots and QNetworkReply:
change this
connect(&_managerDownload, &QNetworkAccessManager::finished, [this](QNetworkReply *reply)
to
connect(&_managerDownload, &QNetworkAccessManager::finished, reply, [this](QNetworkReply *reply)
the reply object in 3rd place should guarantee, that this connect is dissolved once reply is deleted