Um mich mit Qt vertrauter zu machen, schreibe ich gerade einen Feed-Reader. Neben reinen News-Feeds gibt es ja bekanntlich auch solche, die Mediendateien wie Audio- oder Video-Dateien verlinken (Enclosure). Eben solche Dateien möchte ich mit einem einfachen Download-Dialog herunterladen lassen. Das funktioniert mit dem unten zu sehenden Quellcode auch meist sehr gut. Allerdings hängt es davon ab, von welchem Server ich die Dateien anfordere. Bei einigen wird eine 0 Bytes große Datei empfangen, ohne dass ein Verbindungsfehler durch QNetworkReply::error() angezeigt wird. Ich vermute, dass die "Window Size" im TCP-Header modifiziert werden müsste für Server, die nur in kleineren Häppchen ausliefern können. Liege ich da richtig oder liegt das Problem an anderer Stelle? Oder kann man etwas am HTTP-Header der Anforderung (QNetworkRequest) einstellen?
Hier ist die Klassendefinition meines DownloadDialogs (CDownloadDialog). Mit der Klassenvariable "MAXCOUNT" möchte ich dabei nur sicherstellen, dass nur zwei Downloads parallel ausgeführt werden, was aber auf die Downloads selbst keinen Einfluss hat. Ich habe den QUellcode entlang der Dokumentation geschrieben, weshalb ich darin keinen Fehler finden kann.
Code: Alles auswählen
#include "CDownloadDialog.h"
CDownloadDialog::CDownloadDialog() : QDialog(), MAXCOUNT(2)
{
fileName = "";
vBoxLayout = new QVBoxLayout;
this->setLayout(vBoxLayout);
label_url = new QLabel;
vBoxLayout->addWidget(label_url);
progressBar = new QProgressBar;
vBoxLayout->addWidget(progressBar);
label_progress = new QLabel;
vBoxLayout->addWidget(label_progress);
networkAccessManager = new QNetworkAccessManager(this);
connect(this, SIGNAL(rejected()),
this, SLOT(closing()));
};
CDownloadDialog::~CDownloadDialog()
{
delete networkAccessManager;
if (icount > 0)
icount--;
};
void CDownloadDialog::closing()
{
emit downloadFinished(this);
};
int CDownloadDialog::icount = 0;
int CDownloadDialog::count() const
{
return icount;
};
void CDownloadDialog::replyFinished(QNetworkReply* reply)
{
if (icount > 0)
icount--;
label_url->setText("done - " + label_url->text());
QFile file(fileName);
this->setWindowTitle(fileName);
if (file.open(QIODevice::WriteOnly))
file.write(reply->readAll());
file.close();
reply->deleteLater();
emit downloadFinished(this);
};
void CDownloadDialog::replyDownloadProgress(qint64 received, qint64 total)
{
label_progress->setText(QString::number(received) + " / " + QString::number(total) + " Bytes");
if (total < 100)
progressBar->setMaximum((int)total);
else
progressBar->setMaximum(100);
qreal ratio = (qreal)received / (qreal)total;
int value = (int)(ratio * (qreal)100.0);
progressBar->setValue(value);
this->setWindowTitle(QString::number(value) + "% - " + fileName);
};
void CDownloadDialog::replyError(QNetworkReply::NetworkError error)
{
QMessageBox m;
m.setText("error occurred");
m.exec();
};
void CDownloadDialog::downloadFile(QString url, QString targetpath)
{
if (icount + 1 <= MAXCOUNT)
{
QString ext = url.split('.', QString::KeepEmptyParts, Qt::CaseInsensitive).at(url.split('.', QString::KeepEmptyParts, Qt::CaseInsensitive).count() - 1);
QString filename = url.split('/', QString::KeepEmptyParts, Qt::CaseInsensitive).at(url.split('/', QString::KeepEmptyParts, Qt::CaseInsensitive).count() - 1);
QFileDialog* filedialog = new QFileDialog(0, "save file", targetpath + filename, "*." + ext + ";;all files *.*");
filedialog->setAcceptMode(QFileDialog::AcceptSave);
if (filedialog->exec() == QFileDialog::Accepted)
{
fileName = filedialog->selectedFiles()[0];
this->setWindowTitle("0 % - " + fileName);
icount++;
label_url->setText(url);
QNetworkRequest request = QNetworkRequest(QUrl(url));
request.setRawHeader("User-Agent", "QtFeedPad");
QNetworkReply* reply = networkAccessManager->get(request);
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(replyError(QNetworkReply::NetworkError)));
connect(networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
this, SLOT(replyDownloadProgress(qint64,qint64)));
this->show();
}
delete filedialog;
}
else
{
QMessageBox m(QMessageBox::Information, "Information",
"There are " + QString::number(MAXCOUNT) + " downloads running.\nTry again when one has finished.",
QMessageBox::Ok);
m.exec();
emit downloadFinished(this);
}
};Schönen Abend,
*Caesar*