April 29, 2011

spsingh spsingh
Lab Rat
16 posts

Qt Network: urls not loading

 

I have code as follows:

  1. void WebPageLoader::run()
  2. {
  3.  QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
  4.  
  5.  connect(networkManager, SIGNAL(finished(QNetworkReply *)),
  6.    this, SLOT(PageLoaded(QNetworkReply *)));
  7.  
  8.  foreach(QUrl url, mUrls) {
  9.   QNetworkRequest request(url);
  10.  
  11.   networkManager->get(request);
  12.  }
  13. }

The slot PageLoaded is never called. Is there something else one needs to do to get it working?

13 replies

April 29, 2011

mario mario
Lab Rat
209 posts

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

April 29, 2011

Volker Volker
Ant Farmer
5331 posts

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.

April 29, 2011

Andre Andre
Robot Herder
6422 posts

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.

April 29, 2011

mario mario
Lab Rat
209 posts

Andre: That should not be the issue, that’s how you use the request class.

Example from the QNetworkAccessManager doc:

  1. manager->get(QNetworkRequest(QUrl("http://qt.nokia.com")));

[EDIT: code formatting, Volker]

April 29, 2011

Andre Andre
Robot Herder
6422 posts

Yes, you are right. The QNAM API looks a bit asymetric that way. Sorry for the noise!

April 29, 2011

spsingh spsingh
Lab Rat
16 posts

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?

April 29, 2011

Volker Volker
Ant Farmer
5331 posts

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 [developer.qt.nokia.com], don’t miss to read it!

April 29, 2011

mario mario
Lab Rat
209 posts

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.

April 29, 2011

mario mario
Lab Rat
209 posts

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

April 30, 2011

spsingh spsingh
Lab Rat
16 posts

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.

May 1, 2011

Volker Volker
Ant Farmer
5331 posts

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.

May 2, 2011

mario mario
Lab Rat
209 posts

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() [doc.qt.nokia.com] can be used. It will execute a function in a separate thread. This should of course be used together with QFutureWatcher.

May 2, 2011

Volker Volker
Ant Farmer
5331 posts

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.

 
  ‹‹ how to share link of an video to my facebook account and twitter account..      [solved] Qt Signal/Slots in one class but emitted from different threads ››

You must log in to post a reply. Not a member yet? Register here!