Qt Network: urls not loading
-
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?
-
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
-
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.
-
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.
-
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]
-
Yes, you are right. The QNAM API looks a bit asymetric that way. Sorry for the noise!
-
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?
-
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!
-
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.
-
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
-
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.
-
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.
-
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.
-
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.