PDA

View Full Version : qApp->processEvents();



rmagro
12th March 2009, 20:17
Hi Guys,

With the following Qt Code I am trying to send an QHttp request and get the related
response, doing this turning the asynchronous operation into a synchronous one,
without using signals and slots..

Here the code:


http = new QHttp(this);
....
int id = http->request(header, byteArray);

while(http->currentId() != 0)
{
qApp->processEvents();
}

QString result = http->readAll();


In my PC I get the result correctly, in other ones the Gui seems to freeze and the application don't get on..

I am wandering if the "qApp->processEvents();" instruction is the problem and how i can avoid this behaviour..

Using


while(http->currentId() != 0)
{
QCoreApplication::processEvents();
}


would be the same?

If so, what about the fallowing method ??


QNetworkAccessManager manager;
QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(&manager, SIGNAL(finished(QNetworkReply*)),
&q, SLOT(quit()));
QNetworkReply *reply = manager.get(QNetworkRequest(
QUrl("http://www.qtcentre.org")));

tT.start(5000); // 5s timeout
q.exec();

if(tT.isActive()){
// download complete
tT.stop();
} else {
// timeout
}



How to adapt it to perform my task (sending request and waiting for its response before going on with the flow) ???


Many thanks in advance

Roby

wysota
12th March 2009, 23:01
Use the second method, it's beautiful ;)
Your code from the first one is incorrect, anyway. You might employ a local event loop to make it work, but it's a bad idea.

How to use the code? Well... after the exec() call you will either have your reply in the reply object ready to read or a timeout will have occured. The "if" block is there to check which one occured. Then simply do your stuff.

rmagro
13th March 2009, 09:18
many thanks Wysota..

Just to better understand, you mean that the code that follows


while(http->currentId() != 0)
{
QCoreApplication::processEvents();
}

is also incorrect ??

Then, about the second method, I would like you to suggest how to modify the first part of code. I well understand the "if block".

Is it correct like this ?


QHttp *http;
QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(http, SIGNAL(finished(QNetworkReply*)),&q, SLOT(quit()));

//**********************
id = http->request(header, b);
//**********************

tT.start(5000); // 5s timeout
q.exec();

if(tT.isActive()){
//*****************
result = http->readAll();
//*****************
tT.stop();
} else {
// timeout
}


Many thanks in advance

Roby

rmagro
13th March 2009, 09:36
When I use the code:


QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(http, SIGNAL(done(QHttp*)),&q, SLOT(quit()));

//**********************
id = http->request(header, b);
//**********************

tT.start(5000); // 5s timeout
q.exec();

if(tT.isActive()){
//*****************
result = http->readAll();
//*****************
tT.stop();
} else {
// timeout
}


I can't get to the "if" block, then result is always empty..

What wrongs ??

Roby

rmagro
13th March 2009, 09:48
OK Wysota

I made a mistake with the SLOT signal, which is done(bool) in case of http->request..

SO, the code:


QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(http, SIGNAL(done(bool)),&q, SLOT(quit()));

//**********************
id = http->request(header, b);
//**********************

tT.start(600000); // 6minuto timeout
q.exec();

if(tT.isActive()){
//*****************
result = http->readAll();
//*****************
tT.stop();
} else {
QMessageBox::warning(this, "TIME OUT", ("time out"));
// timeout
}


Seem to be ok..

What's your opinin?
Many thanks in advance..

Roby

wysota
13th March 2009, 12:09
Just to better understand, you mean that the code that follows


while(http->currentId() != 0)
{
QCoreApplication::processEvents();
}

is also incorrect ??
No, I mean the loop is incorrect, it would exit too soon.


Is it correct like this ?


QHttp *http;
QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));

Why use QHttp at all if you have a better mechanism available? What's wrong with QNetworkAccessManager?

rmagro
13th March 2009, 12:33
Ok ...I can try to adapt my code to use QNetworkAccessManager
but do you thing something is wrong with the code that follows:



QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(http, SIGNAL(done(bool)),&q, SLOT(quit()));

//**********************
id = http->request(header, b);
//**********************

tT.start(600000); // 6minuto timeout
q.exec();

if(tT.isActive()){
//*****************
result = http->readAll();
//*****************
tT.stop();
} else {
QMessageBox::warning(this, "TIME OUT", ("time out"));
// timeout
}



Thanks

rmagro
13th March 2009, 13:55
Any suggestion to adapt the fallowing code to use the QNetworkAccessManager Class ??



QEventLoop q;
QTimer tT;

tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(http, SIGNAL(done(bool)),&q, SLOT(quit()));

//**********************
id = http->request(header, b);
//**********************

tT.start(5000); 5s
q.exec();

if(tT.isActive()){
//*****************
result = http->readAll();
//*****************
tT.stop();
} else {
QMessageBox::warning(this, "TIME OUT", ("time out"));
// timeout
}

wysota
13th March 2009, 18:34
Ok ...I can try to adapt my code to use QNetworkAccessManager
but do you thing something is wrong with the code that follows:
Yes, I do. There is no way to properly read the incoming data.



Any suggestion to adapt the fallowing code to use the QNetworkAccessManager Class ??
There is nothing to adapt, just take the original code using QNetworkAccessManager.