PDA

View Full Version : Multiple requests with QNetworkAccessManager



ljuhrich
5th June 2013, 20:08
Hi guys,

there is some basic thing I do not understand about the QNetworkAccessManager.
I was told to put only one into the Mainwindow object, used to handle every request caused by my program.
But according to this, how do I distinguish between two request done at nearly the same time — the NAM::finished - signal sends any reply of every kind to the slot it's connected to (let's assume it's named „resp”); but there might be some different action to be applied onto one of these replies.
For instance, at one time the program loads the XML file to find new updates. Also, there is requested The basic profile information of a facebook-user. Both is done with the NAM, so how do I find out if the incoming reply is the update or the profile data?

Greets, Lukas :)

wysota
5th June 2013, 20:28
Have a look at what QNetworkAccessManager::get() (or put()) returns.

ljuhrich
5th June 2013, 20:49
Ah, sounds like I should connect the finished() signal of the returned QNetworkReply to the manual handling function, like this:


void Manwindow::requestUpdates()
{
// updateReply is declared publicly in the Mainwindow class
conect(updateReply, SIGNAL(finished()), this, SLOT(handleUpdateXML()));
updateReply = NAM.get( /* get Request stuff in here */ );
}

void MainWindow::handleUpdateXML()
{
QString xml = QString::fromUTF8(updateReply->readAll());
// Actions beng performed to read the XML data and so on...
updateReply->deleteLater();
}
Well, there are possibly some syntax errors, I just wanna know if I'm right with my basic idea of doing it correctly ;)

thx for quick reply, Lukas

ChrisW67
5th June 2013, 21:03
Right general idea.
Line 4 and 5 are the wrong way around, you need the pointer that get() or post() returns before you can connect() it to a slot.
Line 10, you will get here on error conditions too, so best check for success.

anda_skoa
6th June 2013, 10:58
You can also use QObject::sender() to get the reply object in the finished slot


void MainWindow::handleUpdateXML()
{
QNetworkReply *updateReply = qobject_cast<QNetworkReply*>(QObject::sender());

QString xml = QString::fromUTF8(updateReply->readAll());
// Actions beng performed to read the XML data and so on...
updateReply->deleteLater();
}


Even if you are only using one slot for all replies, you can still identify the request because each reply object contains the QNetworkRequest it was created for

Cheers,
_

ljuhrich
6th June 2013, 15:38
So the correct code would be like

void Manwindow::requestUpdates()
{
QNetworkmanager *NAM = new QNetworkManager();
// updateReply is declared publicly in the Mainwindow class (?)
updateReply = NAM.get( /* get Request stuff in here */ );
conect(updateReply, SIGNAL(finished()), this, SLOT(handleUpdateXML()));
}

void MainWindow::handleUpdateXML()
{
QString xml = QString::fromUTF8(updateReply->readAll());
// Actions beng performed to read the XML data and so on...
updateReply->deleteLater();
}

Is it necessary to declare the QNetworkReply globally e.g. in the mainwindow-class or can it be defined locally too — does a updateReply->deleteLater(); prevent it to be deleted after leaving the procedure (as I learned it)?

Greets, Lukas

PS: thx for showing me the QObject::sender() opportunity, but I'll keep it working in separate procedures :)

ChrisW67
7th June 2013, 04:29
I would not allocate a new QNetworkAccessManager for each request, just create it once (member variable or on heap) once and reuse it. Don't forget to manage the QNAM memory if you do allocate it on the heap.

anda_skoa
7th June 2013, 08:34
Is it necessary to declare the QNetworkReply globally e.g. in the mainwindow-class or can it be defined locally too

It can be done locally as you can use QObject::sender() to retrieve the pointer in the slot connected to finish().



oes a updateReply->deleteLater(); prevent it to be deleted after leaving the procedure (as I learned it)?

It is not being deleted automatically because the caller (your code) becomes the owner of the pointer.
deleteLater() allows you to schedule deletion, i.e. defer it to another run of the event loop. Calling delete on the pointer inside a slot connected to the object's signal on the other hand would not be good:)

Cheers,
_