PDA

View Full Version : Waiting for readyread and requestfinished signal



srohit24
9th July 2009, 07:50
I am building a app that contacts the server for data, gets it and then does some processing before displaying the result.

I have created a mapping function that maps all the functions that need to be called if a particular request has to be successful.

This code is the main part where all the calling is done.


if (check_if_clientID_is_present())
call = "teci.create.client";
qDebug() << "call"<< call;

if(!call.isEmpty() && API_Request_Pointer == false)
mapping(call);


This is the mapping code where the required functions are called.
First i prepare the xml document, call the fetch function, then wait for the readyread and requestfinished signals, then call the parsing function and then exit the mapping function


void MainWindow::mapping(QString callname)
{
qDebug() <<"in mapping";
QThread thread;
if(call.compare("teci.create.client",callname)== 0)
{
qDebug() <<"inside create client";
API_Request_Pointer = true;
create_client();
fetch();
connect(&http, SIGNAL(readyRead(const QHttpResponseHeader &)),
this, SLOT(readData(const QHttpResponseHeader &)));

connect(&http, SIGNAL(requestFinished(int, bool)),
this, SLOT(finished(int, bool)));
parse_create_client();
API_Request_Pointer = false;
qDebug() <<"leaving create client";
}
else if (call.compare("teci.test.reverse",callname)== 0)
{
API_Request_Pointer = true;
reverse_string();
fetch();
connect(&http, SIGNAL(readyRead(const QHttpResponseHeader &)),
this, SLOT(readData(const QHttpResponseHeader &)));

connect(&http, SIGNAL(requestFinished(int, bool)),
this, SLOT(finished(int, bool)));
parse_reverse_string();
API_Request_Pointer = false;
}
qDebug() <<"leaving mapping";

}


void MainWindow::fetch()
{

xml.clear();

QByteArray string ("username");
string.append(":");
string.append("12345");
QString encoded = string.toBase64();
qDebug() <<"String"<< string <<"Encoded" <<encoded ;

QUrl url("http://..../");
url.setUserName("username");
url.setPassword("12345");

QHttpRequestHeader header("POST","/api/");
header.setValue("Host",url.host());
header.setValue("Path",url.path());
header.setValue("Authorization","Basic " + encoded);

http.setHost(url.host(),url.port(80));

connectionId = http.request(header,xmlrequest);
qDebug() << "Leaving fetch";
}


void MainWindow::create_client()
{
here i add tags and create the xml

xmlrequest.append(doc.toString());
qDebug() << xmlrequest.data();



void MainWindow::readData(const QHttpResponseHeader &resp)
{


if (resp.statusCode() != 200)
http.abort();
else
{
xml.addData(http.readAll());
}
qDebug() << "Leaving readdata";
}


void MainWindow::finished(int id, bool error)
{
qDebug() <<"Error" <<http.errorString();
if (error)
qWarning("Received error during HTTP fetch.");

qDebug() << "Leaving finished";
}


void MainWindow::parse_create_client()
{
qDebug() <<"Entering parser";
while (!xml.atEnd())
{
xml.readNext();
qDebug()<<xml.readNext();
if (xml.isStartElement())
{
currentTag = xml.name().toString();

if (currentTag == "client")
API_key += xml.attributes().value("key").toString();
qDebug() << "CurrentTag"<<currentTag;

}

else if (xml.isCharacters() && !xml.isWhitespace())
{

if (currentTag == "password")
API_password += xml.text().toString();
}
}

qDebug() << "webiste_clientID"<< API_key;
qDebug() << "webiste_serial no"<<API_password;

}
}


After reading the data, i write it down in a file.

This is the output i am getting.


Getting data from the webiste
call "teci.create.client"
in mapping
inside create client
<request version="0.1" >
<call name="teci.client.create" >
<client>
<kind>MOBILE</kind>
<name>API Test suite 7001</name>
</client>
</call>
</request>

Leaving fetch
Entering parser
1
webiste_clientID ""
webiste_serial no ""
leaving create client
leaving mapping
Leaving finished
Leaving readdata


the readyread and requestfinished signals are being called after the parsing function has been called.

How can i wait for the signal and then call the parsing function??

wysota
9th July 2009, 07:58
Either use waitForReadyRead() or call the parsing method from a slot connected to both signals you are waiting for where you will check if you received both of them or read this article Keeping the GUI Responsive.

srohit24
9th July 2009, 08:08
can u please gimme the code to wait for both the signals at the same time?

wysota
9th July 2009, 08:25
No, I can't. But you can read the article and write it yourself :)

Of course if you posted in the newbie section of the forum, I might have helped you a bit more but since you don't consider yourself a newbie, I'm sure your skills are enough to transform the code properly.

nish
9th July 2009, 08:33
can u please gimme the code to wait for both the signals at the same time?
rohit bhai.. this thing does not work anywhere.

wysota
9th July 2009, 08:44
can u please gimme the code to wait for both the signals at the same time?

Actually I can give you the code. But only if you give me your salary (or equivalent) for writing the application. I don't think that's worth it, is it?

nish
9th July 2009, 08:51
Actually I can give you the code. But only if you give me your salary (or equivalent) for writing the application. I don't think that's worth it, is it?
cool man cool down :). he got enough.

srohit24
9th July 2009, 08:59
i would have given u my salary but i am not working for anyone nor earning a salary.

i am just working in Qt to complete a project for this semester.

I have had a lot of help from this forum, so got a bit carried away :)

Anyway, any hints or clue to complete this particular task huh? ;)

wysota
9th July 2009, 09:02
i would have given u my salary but i am not working for anyone nor earning a salary.

i am just working in Qt to complete a project for this semester.
So maybe a salary for all the projects you will ever participate in thanks to the education you are going to receive?


I have had a lot of help from this forum, so got a bit carried away :)

Anyway, any hints or clue to complete this particular task huh? ;)

Please read the article I pointed you to. Then use QEventLoop or move your parsing code to another method which will be called when both signals are flagged as received.

srohit24
9th July 2009, 09:37
If u really wanted returns for your help, in cash, you wouldnt be helping others out, almost every day in this forum :)

I split the creating and parsing xml into two parts.

I am calling the creating b4 fetch and then parsing it in the readData fucntion


void RSSListing::readData(const QHttpResponseHeader &resp)
{


if (resp.statusCode() != 200)
http.abort();
else
{
xml.addData(http.readAll());
if(call.compare("teci.create.client",call)== 0)
{
qDebug() <<"inside parse create client";
parse_create_client();
API_Request_Pointer = false;

}
else if (call.compare("teci.test.reverse",call)== 0)
{
qDebug() << "Enter parse string reverse";
parse_reverse_string();
API_Request_Pointer = false;
}
}

wysota
9th July 2009, 12:05
If u really wanted returns for your help, in cash, you wouldnt be helping others out, almost every day in this forum :)
Damn... you got me figured out... :crying: