Qt Network: urls not loading
-
wrote on 29 Apr 2011, 06:49 last edited by
I have code as follows:
@void WebPageLoader::run()
{
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);connect(networkManager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(PageLoaded(QNetworkReply *)));foreach(QUrl url, mUrls) {
QNetworkRequest request(url);networkManager->get(request);
}
}@The slot PageLoaded is never called. Is there something else one needs to do to get it working?
-
wrote on 29 Apr 2011, 07:15 last edited by
Maybe you should consider changing the code a bit because you will keep a QNetworkAccessManager instance for each call to run until you delete the parent. Maybe you should just create a network manager in the parent's constructor and use that instance from the run method
-
wrote on 29 Apr 2011, 09:59 last edited by
The code should work, there's something different going wrong. Can you provide us a complete sample program demonstrating the behavior, please. Just a small main.cpp and a reduced class.
-
wrote on 29 Apr 2011, 10:08 last edited by
I think the culprit is line 9. You create the request on the stack instead of on the heap. That means the request gets deleted as soon as the code hits line 12.
-
wrote on 29 Apr 2011, 10:11 last edited by
Andre: That should not be the issue, that's how you use the request class.
Example from the QNetworkAccessManager doc:
@manager->get(QNetworkRequest(QUrl("http://qt.nokia.com")));@
[EDIT: code formatting, Volker]
-
wrote on 29 Apr 2011, 10:38 last edited by
Yes, you are right. The QNAM API looks a bit asymetric that way. Sorry for the noise!
-
wrote on 29 Apr 2011, 11:23 last edited by
My Bad. WebPageLoader is a QThread which exits before the slot PageLoaded is called. What is the best practice to wait for all slots to have done their job before exiting the run?
-
wrote on 29 Apr 2011, 11:28 last edited by
As QNAM is asynchronous already, there is hardly any need to put it into a separate thread.
If you really need to use a thread, call exec() in your run method. This starts a local event loop and keeps the thread running until you call quit().
Be aware of the implications regarding object owners, signals and slots. Peppe has written a great wiki article on "Threads, Events and QObjects":http://developer.qt.nokia.com/wiki/Threads_Events_QObjects, don't miss to read it!
-
wrote on 29 Apr 2011, 11:38 last edited by
When do you delete the WebPageLoader? If that happens before you receive the response the NAM will be deleted and the request aborted.
My second guess is that you need to execute the event-loop if you're creating the NAM inside the thread, else no requests will be dispatched.
-
wrote on 29 Apr 2011, 11:41 last edited by
Yeah, try it out w/o threading as Volker suggested since NAM is async. If you still have issues when processing the response maybe you can handle that in a separate thread
-
wrote on 30 Apr 2011, 12:22 last edited by
thanks Volker for the wonderful link. The problem was that the emitter and the receiver are in separate threads causing a queued connection which requires an evwnt loop in the thread. caling exec in the thread solved the problem.
-
wrote on 1 May 2011, 19:32 last edited by
Good to hear, it runs now.
Did you consider dropping the QThread stuff? QNAM is asynchronous already, so it should be easy to put it into the main thread.
-
wrote on 2 May 2011, 06:29 last edited by
But the processing of the reply (my slot) is running in the main thread, or I'm I wrong?
To prevent the main thread from blocking while doing heavy processing in the reply-slot, "QtConcurrent::run()":http://doc.qt.nokia.com/4.7/qtconcurrentrun.html can be used. It will execute a function in a separate thread. This should of course be used together with QFutureWatcher.
-
wrote on 2 May 2011, 14:41 last edited by
I don't know - if you did not put it into a separate thread, it runs in the main loop, yes. If the main thread is blocking depends on how much work is done in your slot. If it's heavy-loaded, a separate thread can be a solution, but it has the drawback, that you cannot manipulate the GUI from it. You can send queued signals to slots of the GUI, though.
10/14