PDA

View Full Version : QNetworkAccessManager - finished() signal is never triggered!



Alaa Elrifaie
27th July 2014, 19:32
Hi there guys,

I've asking this question on a lot of websites for the past few days, but I've been out of luck appearently! No one could help me, so I hope you guys can figure out the problem & how to solve it.



I'm trying to use QNetworkAcessManager to get the source of a url .. But it seems that there's a problem with the signal-slot complex!
my onFinished() slot is never triggered! Why?

Here's my code:


void Worker::start(QString url)
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
QObject::connect(reply, SIGNAL(finished()), this, SLOT(onFinished()));


void Worker::onFinished()
{
qDebug() << "Slot has been triggered!";

QString html = reply->readAll();
}


And actually I tried to play around & change the code many times without any luck, so please guide me & show me a nice working example to get html source of a webpage.



And thank you so much in advance;

Infinity
27th July 2014, 20:35
I don't know exactly what the problem is, but:
1. One QNetworkAccessManager should be enough for the whole Qt application. Ensure the QNetworkAccessManager gets deleted properly when not needed anymore.
2. If you're using Qt 5 use the new syntax to connect signals and slots.
3. Returns QObject::connect(...) a valid connection? (you can test that using qDebug() as well)
4. Use deleteLater() to delete the reply after reading the data.

Alaa Elrifaie
27th July 2014, 20:52
I don't know exactly what the problem is, but:
1. One QNetworkAccessManager should be enough for the whole Qt application. Ensure the QNetworkAccessManager gets deleted properly when not needed anymore.
2. If you're using Qt 5 use the new syntax to connect signals and slots.
3. Returns QObject::connect(...) a valid connection? (you can test that using qDebug() as well)
4. Use deleteLater() to delete the reply after reading the data.


Yup, using debug() I can verify that the SIGNAL-SLOT connection was done successfully!
I'm using Qt 5.3.1, but I don't know about this new syntax you're talking about.
Actually I'm doing just a simple code to see why this isn't working for me, so could you please give me a working solution? My code compiles but doesn't work!

anda_skoa
27th July 2014, 21:08
Is the application's event loop running, or in case of a secondary thread, the thread's event loop?

Btw, your code stores the reply pointer in a function-local variable called reply, the slots accesses apparently a member with the same name.

Cheers,
_

Infinity
27th July 2014, 22:36
could you please give me a working solution
There are lots of examples: http://qt-project.org/doc/qt-5/examples-network.html

I'm using Qt 5.3.1, but I don't know about this new syntax you're talking about.
http://qt-project.org/doc/qt-5/qobject.html#connect-4
But this should not be the reason for your problem (it was more a recommendation).

Alaa Elrifaie
28th July 2014, 15:00
Is the application's event loop running, or in case of a secondary thread, the thread's event loop?

Btw, your code stores the reply pointer in a function-local variable called reply, the slots accesses apparently a member with the same name.

Cheers,
_

Actually, I'm a newbie with Qt, I don't know what's happening while I'm doing everything as supposed to ( I read documentations all the time! ).
I could do the mission ( synchronously ) but I hope to do it asynchronously.


There are lots of examples: http://qt-project.org/doc/qt-5/examples-network.html

http://qt-project.org/doc/qt-5/qobject.html#connect-4
But this should not be the reason for your problem (it was more a recommendation).

I've seen all these before, but when I do what I see there, nothing works!

Eventually I could achieve what I want using this synchronous code:

QNetworkAccessManager manager;
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
QNetworkReply *response = manager.get(request);
QEventLoop event;
connect(response,SIGNAL(finished()),&event,SLOT(quit()));
event.exec();
QString html = response->readAll(); // Source should be stored here

But I need it to be asynchronous, so I tried to change it to something like:

QNetworkAccessManager manager;
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
QNetworkReply *response = manager.get(request);
connect(response, SIGNAL(finished()), this, SLOT(onFinished()));
But again, slot is never triggered!

anda_skoa
29th July 2014, 09:23
That last piece won't work because the network manager is destroyed at the end of the scope it is created in (created on the stack).

Since the code snippets you post are correct in themselves, the problem must be elsewhere.

Could you post a buildable example of what you have or at least show the main function and how it creates this worker object?

Cheers,
_

jefftee
7th August 2014, 06:43
Hi, since your class name is Worker, I am guessing that you might be running this code in a separate thread. Are you sure there's an event loop running in your thread?

Can you show how you have created the Worker, the QThread, etc?

Edit: apologies, I see anda_skoa asked about the event loop in a prior reply... :)