Witam, mam problem, na stronie bogotobogo.com znalazłem kod programu pobierającego pliku z internetu. Problem jest taki, że gdy cały kod mam w głównej klasie programu to wszystko działa, a w oddzielnej klasie wyskakuje problem z utworzeniem nowego objektu klasy QNetworkAccessManager.
Kod programu :
qDownloader.h
#ifndef QDOWNLOADER_H
#define QDOWNLOADER_H
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QProgressDialog>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QMessageBox>
#include <QTime>
#include <QDebug>
#include <QString>
class qDownloader : public QObject
{
Q_OBJECT
public:
qDownloader();
public:
void download_clicked(QUrl url);
void startRequest(QUrl url);
private slots:
void httpReadyRead();
void httpDownloadFinished();
void updateDownloadProgress(qint64, qint64);
void cancelDownload();
public:
QNetworkAccessManager *manager;
private:
QUrl url;
//QNetworkAccessManager *manager;
QNetworkReply *reply;
QProgressDialog *progressDialog;
QFile *file;
qint64 fileSize;
qint64 fileSpeed;
QTime t;
bool httpRequestAborted;
};
#endif // QDOWNLOADER_H
qDownloader.cpp
#include "qdownloader.h"
qDownloader::qDownloader()
{
}
void qDownloader::download_clicked(QUrl url)
{
manager = new QNetworkAccessManager(NULL);
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
if(fileName.isEmpty())
fileName = "index.html";
if(QFile::exists(fileName)){
if(QMessageBox::question(0, "HTTP", "Plik %1 już istnieje. Czy chcesz go nadpisać ?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
return;
QFile::remove(fileName);
}
file = new QFile(fileName);
if(!file->open(QIODevice::WriteOnly)){
QMessageBox::information(0, "HTTP", "Nie można zamiać pliku %1: %2.");
delete file;
file = 0;
return;
}
httpRequestAborted = false;
qDebug() << "Pobieranie " << fileName;
startRequest(url);
}
void qDownloader::httpReadyRead()
{
if(file)
file->write(reply->readAll());
}
void qDownloader::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes)
{
qint64 predkosc = ((bytesRead - fileSpeed) * (t.elapsed() / 10)) / 1024;
t.start();
fileSpeed = bytesRead;
if(httpRequestAborted)
return;
bytesRead = (bytesRead / 1024) / 1024;
totalBytes = (totalBytes / 1024) / 1024;
qDebug() << "Prędkość pobierania wynosi : " << predkosc;
qDebug() << "Pobrano " << bytesRead << " z " << totalBytes << endl;
}
void qDownloader::cancelDownload()
{
httpRequestAborted = true;
reply->abort();
}
void qDownloader::httpDownloadFinished()
{
// when canceled
if(httpRequestAborted){
if(file){
file->close();
file->remove();
delete file;
file = 0;
}
reply->deleteLater();
progressDialog->hide();
return;
}
// download finished normally
progressDialog->hide();
file->flush();
file->close();
// get redirection url
QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if(reply->error()){
file->remove();
QMessageBox::information(0, "HTTP", "Download failed: %1.");
}else if(!redirectionTarget.isNull()){
QUrl newUrl = url.resolved(redirectionTarget.toUrl());
if(QMessageBox::question(0, "HTTP", "Redirect to %1 ?", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
url = newUrl;
reply->deleteLater();
file->open(QIODevice::WriteOnly);
file->resize(0);
startRequest(url);
return;
}
}else{
QString fileName = QFileInfo(url.path()).fileName();
}
reply->deleteLater();
reply = 0;
delete file;
file = 0;
manager = 0;
}
void qDownloader::startRequest(QUrl url)
{
reply = manager->get(QNetworkRequest(url));
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDownloadProgress(qint64,qint64)));
connect(reply, SIGNAL(finished()), this, SLOT(httpDownloadFinished()));
}
Tworzenie nowego obiektu klasy qDownloader :
nienazwany.h
private:
qDownloader *m;
I wywołanie w głównej funkcji :
nienazwany.cpp
m->download_clicked(QUrl("http://link-do-pliku-ktory-chce-pobrac.exe"));
Debugger zwraca :
The inferior stooped because it triggered an exception.
Stopped in thread 0 by: Exception at 0xb58f91, code: 0xc0000005: write access violation at: 0x1, flags=0x0 (first chance).