QHttp in eigener classe / signal probleme
Verfasst: 10. Mai 2006 10:19
Hallo Alle,
ich habe ein Problem mit einem Downloadmanager den ich z.Z. schreibe.
Ich habe mir an Hand des HTTP-Examples eine "downloader Klasse" geschrieben.
In meinem Hauptprogram verknüpfe ich ein Signal aus dieser mit meinem Hauptprogram.
Mein Problem ist nun das ich egal wo ich das Signal in meinem Fall (downloadDone(QString)) auslöse, der Download eigentlich noch garnicht fertig ist.
D.h. Löse ich am Ende von QHttp::requestFinished aus oder von QHttp::done oder frage zwischendurch den QHttp::stateChanged nach dem Wert null ab alles wird schon ausgelöst bevor die Datei fertig geladen ist.
Downloader Klasse:
Downlaoder Header:
Entsprechender Abschnitt in der Hauptklasse:
Ich vermute mal das es damit zusammenhängt das die SocketConnection die in QHttp gestarted wird threaded ist.
Vielen Dank im Vorraus!
ich habe ein Problem mit einem Downloadmanager den ich z.Z. schreibe.
Ich habe mir an Hand des HTTP-Examples eine "downloader Klasse" geschrieben.
In meinem Hauptprogram verknüpfe ich ein Signal aus dieser mit meinem Hauptprogram.
Mein Problem ist nun das ich egal wo ich das Signal in meinem Fall (downloadDone(QString)) auslöse, der Download eigentlich noch garnicht fertig ist.
D.h. Löse ich am Ende von QHttp::requestFinished aus oder von QHttp::done oder frage zwischendurch den QHttp::stateChanged nach dem Wert null ab alles wird schon ausgelöst bevor die Datei fertig geladen ist.
Downloader Klasse:
Code: Alles auswählen
#include <QHttp>
#include <QFile>
#include <QFileInfo>
#include <QHttpResponseHeader>
#include <QUrl>
#include <QObject>
#include <QMessageBox>
#include "dler.h"
downLoader::downLoader(QObject *parent) : QObject(parent) {
http = new QHttp;
connect(http, SIGNAL(requestFinished(int, bool)),
this, SLOT(httpRequestFinished(int, bool)));
connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
}
void downLoader::downloadFile(QString myUrl) {
QUrl url(myUrl);
QFileInfo fileInfo(url.path());
if(myUrl.indexOf("?") != -1) {
url.setPath(myUrl.right(myUrl.size()-(myUrl.indexOf(url.host())+url.host().size())));
}
QString fileName = fileInfo.fileName();
if (QFile::exists(fileName)) {
return;
}
file = new QFile(fileName);
if (!file->open(QIODevice::WriteOnly)) {
delete file;
file = 0;
return;
}
http->setHost(url.host(), url.port() != -1 ? url.port() : 80);
if (!url.userName().isEmpty()) http->setUser(url.userName(), url.password());
httpRequestAborted = false;
httpGetId = http->get(url.path(), file);
}
void downLoader::cancelDownload() {
httpRequestAborted = true;
http->abort();
}
void downLoader::httpRequestFinished(int requestId, bool error) {
if (httpRequestAborted) {
if (file) {
file->close();
file->remove();
delete file;
file = 0;
}
return;
}
if (requestId != httpGetId) return;
file->close();
if (error) {
file->remove();
}
delete file;
file = 0;
if(http->state() == 0 && !error) emit downloadDone(tr("trusted"));
if(http->state() == 0 && error) emit downloadDone(tr("trusted but failed\nerror:%1").arg(http->errorString()));
if(http->state() != 0 && !error) {
http->close();
emit downloadDone(tr("untrusted"));
}
if(http->state() != 0 && !error) {
http->close();
emit downloadDone(tr("untrusted and failed\nerror:%1").arg(http->errorString()));
}
}
void downLoader::readResponseHeader(const QHttpResponseHeader &responseHeader) {
if (responseHeader.statusCode() != 200) {
httpRequestAborted = true;
http->abort();
}
}
Code: Alles auswählen
#ifndef DLER_H
#define DLER_H
#include <QObject>
class QHttp;
class QFile;
class QHttpResponseHeader;
//Downloader object
class downLoader : public QObject {
Q_OBJECT
public:
downLoader(QObject *parent = 0);
void downloadFile(QString myUrl);
signals:
void downloadDone(QString checkType);
private slots:
void cancelDownload();
void httpRequestFinished(int requestId, bool error);
void readResponseHeader(const QHttpResponseHeader &responseHeader);
private:
QHttp *http;
QFile *file;
int httpGetId;
bool httpRequestAborted;
};
#endif
Code: Alles auswählen
void MainWin::load_sites(QString lastCheck) {
if(act_site > 0) logger(tr("Site nr. %1 done with: %2").arg(act_site-1).arg(lastCheck));
logger(tr("Downloading site nr. %1").arg(act_site+1));
if(act_site > site_list.size()) return;
connect(siteLoader, SIGNAL(downloadDone(QString)), this, SLOT(load_sites(QString)));
siteLoader->downloadFile(site_list[act_site].getUrl());
act_site++;
}
Vielen Dank im Vorraus!