Using QThread and QNetworkAccessManager
-
I am trying to make my desktop app execute some Internet lookups in the background and planned on having the background thread send a signal to my main thread when completed w/the data found or network error. I am starting the thread just fine but it never seems to execute. The output is:
@Running QrzCallbook thread
QUrl( "http://localhost/xml?callsign=AA1AA" )@The header is:
@#ifndef QRZCALLBOOK_H
#define QRZCALLBOOK_H#include <QThread>
#include <QUrl>
#include <QNetworkAccessManager>
#include <QNetworkReply>class QrzCallbook : public QThread
{
Q_OBJECTpublic:
explicit QrzCallbook(QObject *parent = 0) : QThread(parent) {}virtual void lookup(QString call) { callsign = call; start(); } virtual void run();
signals:
void stationData(const QString& name);
void networkError(const QString errorMessage);
void parseError(const QString errorMessage);private slots:
void downloadFinished();private:
QNetworkAccessManager *netAccessMgr;
QNetworkReply *netReply;
QString callsign;
};#endif // QRZCALLBOOK_H@
The class file is:
@#include <QNetworkRequest>
#include "SmartLog.h"
#include "QrzCallbook.h"void QrzCallbook::run()
{
qDebug() << "Running QrzCallbook thread";QUrl thisUrl("http://localhost/xml"); thisUrl.addQueryItem("callsign", callsign); qDebug() << thisUrl; netAccessMgr = new QNetworkAccessManager; netReply = netAccessMgr->get(QNetworkRequest(thisUrl)); connect(netReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
}
void QrzCallbook::downloadFinished()
{
qDebug() << "Download has finished";
netAccessMgr->deleteLater();
netReply->deleteLater();if (netReply->error()) { qDebug() << netReply->errorString(); emit networkError(netReply->errorString()); return; } qDebug() << netReply->readAll(); emit stationData("Not Implemented");
}
@Any thoughts on why the downloadFinished() slot is never run?
Jeremy
-
I think I understand what's going on here. A request is made to download a web page, signals/slots are connected and then my thread terminates before the results are returned, thus I never get a download.
How do I tell my thread to remain active until a download is complete?
-
I originally had it to not use a thread and when doing a lookup the GUI hangs for about 1 1/2 seconds when the action is executed. With this particular action if call server #1 doesn't have the callsign on file then a subsequent request will go out to another callbook server. That created another 1 1/2 second GUI freeze. I am not certain where the "freeze" occurs at. Here is my non-threaded code output:
@Running QrzCallbook thread: 0
Requesting: 0
Done Requesting: 1
Download has finished: 1765
Reading data: 1765
Done reading: 1765@There is no delay in the "run" method, nor any in the "downloadFinished" method but the GUI hangs. By hang I mean I cannot use my arrow keys to move around in the field, tab ceases to work and clicking with my mouse on any new field does not function for about 1 1/2 seconds. The event is triggered in a slot responding to a QLineEdit's textChanged signal.
Here is the non-threaded source .h:
@class QrzCallbook : public QObject
{
Q_OBJECTpublic:
explicit QrzCallbook(QObject *parent = 0) : QObject(parent) {}virtual void lookup(QString call) { callsign = call; run(); } virtual void run();
signals:
void stationData(const QString& name);
void networkError(const QString errorMessage);
void parseError(const QString errorMessage);private slots:
void downloadFinished();private:
QNetworkAccessManager *netAccessMgr;
QNetworkReply *netReply;
QString callsign;
QTime timer;
};@And the non-threaded .cpp:
@void QrzCallbook::run()
{
timer.start();qDebug() << "Running QrzCallbook thread: " << timer.elapsed(); QUrl thisUrl("http://localhost/xml"); qDebug() << "Requesting: " << timer.elapsed(); netAccessMgr = new QNetworkAccessManager; netReply = netAccessMgr->get(QNetworkRequest(thisUrl)); connect(netReply, SIGNAL(finished()), this, SLOT(downloadFinished())); qDebug() << "Done Requesting: " << timer.elapsed();
}
void QrzCallbook::downloadFinished()
{
qDebug() << "Download has finished: " << timer.elapsed();
netAccessMgr->deleteLater();
netReply->deleteLater();if (netReply->error()) { qDebug() << netReply->errorString(); emit networkError(netReply->errorString()); return; } qDebug() << "Reading data: " << timer.elapsed(); QByteArray data = netReply->readAll(); qDebug() << "Done reading: " << timer.elapsed(); emit stationData("Not Implemented");
}@
So... to answer your question, I am trying to get rid of the 1 1/2 second delay that occurs.
Jeremy