PDA

View Full Version : QThread and QNetworkAccessManger



dpatel
24th October 2010, 04:47
Hi,

I am trying to create a worker thread which will get the html of links that are in string list.

When I run the program I get following warning when the thread tries to connect finished() signal of QNetworkManager object.

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNetworkAccessManager(0x3aa790), parent's thread is QThread(0x3aa560), current thread is WorkerThread(0x28fe54)

The code is as below



//WorkerThread.h


#include <QThread>
#include <QStringList>

class QNetworkReply;
class QNetworkAccessManager;

class WorkerThread : public QThread
{
Q_OBJECT
public:
WorkerThread();
~WorkerThread();
void startLoadingWebPages(const QStringList& list);
protected:
virtual void run();
QStringList List;
private:
QNetworkAccessManager *m_pNetworkAccessManager;

public slots:
void replyFinished(QNetworkReply *);

};

//WorkerThread.cpp
//Worker thread constructor
WorkerThread::WorkerThread():
{
m_pNetworkAccessManager = new QNetworkAccessManager();
connect(m_pNetworkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
}
void WorkerThread::startLoadingWebPages(const QStringList &links)
{
m_WebPageLinkList=links;
start();
}

void WorkerThread::run()
{
// QString link=m_WebPageLinkList.at(m_LinkIndex);
foreach(QString string,m_WebPageLinkList)
{
qDebug(string.toAscii().data());
m_pNetworkAccessManager->get(QNetworkRequest(QUrl(string)));
}
exec();
}

void WorkerThread::replyFinished(QNetworkReply* pReply)
{
QString webData(pReply->readAll());
qDebug(QString::number(webData.length()).toAscii() .data());
}



Can some one please help me out.
Also when the slot replyFinished gets called the QNetworkReply->readAll() returns empty buffer.

tbscope
24th October 2010, 07:07
The classic pitfall of QThread.


m_pNetworkAccessManager->get(QNetworkRequest(QUrl(string)));

The QNetworkRequest and m_pNetworkAccessManager live in different threads.
QThread by itself is not a new thread. A QThread object lives in the main thread. It only starts and manages a single new thread. Only the code in the run() function will be performed in a new thread.

To make it yourself easy, do not subclass QThread. Leave it like it is.
Instead, move all your code into a new QObject subclass. Then move the QObject object to the new QThread object using moveTothread.

By the way, since the QNetwork classes can work asynchronously, you do not need to use threads. These classes will not block the main event loop.