2014-10-15 5 views
1

Я пытаюсь сделать код в этом вопросе работы. qt - how to download and save image via http?QT Загрузка файла с QNetworkAccessManager

Он создает файлы, но данные не записываются. Мое лучшее предположение, что подключение к синглам и слотам не работает. Что я делаю неправильно?

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

namespace Ui { 
class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    QString getPageImage(QString url = ""); 
    bool saveToDisk(const QString &filename, QIODevice *data); 
    ~MainWindow(); 

private slots: 
    void on_btnDownload_clicked(); 

private: 
    Ui::MainWindow *ui; 
}; 

#endif // MAINWINDOW_H 

qdownload.h

#ifndef QDOWNLOADER_H 
#define QDOWNLOADER_H 

#include <QObject> 
#include <QNetworkAccessManager> 
#include <QNetworkRequest> 
#include <QNetworkReply> 
#include <QFile> 
#include <QStringList> 
#include <QDir> 
#include <QDebug> 

class QDownloader : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit QDownloader(QObject *parent = 0); 
    virtual ~QDownloader(); 
    void setFile(QString fileURL, QString folderName, QString fileName); 

private: 
    QNetworkAccessManager *manager; 
    QNetworkReply *reply; 
    QFile *file; 

private slots: 
    void onDownloadProgress(qint64,qint64); 
    void onFinished(QNetworkReply*); 
    void onReadyRead(); 
    void onReplyFinished(); 
}; 

#endif // QDOWNLOADER_H 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 
#include "QNetworkAccessManager" 
#include "QNetworkReply" 
#include "QFile" 
#include "QDebug" 
#include "QUrl" 
#include "QStringList" 
#include "qdownloader.h" 
#include <QTimer> 


MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    ui->progressBar->setVisible(false); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::on_btnDownload_clicked() 
{ 
    QString link = ui->txtURL->text(); 
    int issue = ui->sbIssue->value(); 
    ui->progressBar->setMaximum(issue); 
    ui->progressBar->setValue(0); 
    ui->progressBar->setVisible(true); 
    for(int j = 1; j <= issue; j++){ 
     int i = 1; 
     while(getPageImage(link + "/" + QString::number(j) + "/" + QString::number(i) + "/").length() > 0){ 
      QString filename = "http://" + getPageImage(link + "/" + QString::number(j) + "/" + QString::number(i) + "/"); 
      qDebug() << filename; 
      QDownloader qDL; 
      qDL.setFile(filename,ui->txtTitle->text() + "_" + QString::number(j),ui->txtTitle->text() + "_" + QString::number(j) + "_" + QString::number(i)); 
      //qDebug() << getPageImage(link + "/" + QString::number(j) + "/" + QString::number(i) + "/").length(); 
      i++; 
     } 
     ui->progressBar->setValue(j); 
    } 
    ui->progressBar->setVisible(false); 
} 


QString MainWindow::getPageImage(QString url){ 
    QString pic = ""; 
    if(url.length() > 0){ 
     QNetworkAccessManager manager; 
     QNetworkReply *response = manager.get(QNetworkRequest(QUrl(url))); 
     QEventLoop event; 
     connect(response,SIGNAL(finished()),&event,SLOT(quit())); 
     event.exec(); 
     QString html = response->readAll(); 

     if(html.length() > 0){ 
      QStringList str; 
      str = html.split("\n"); 
      //qDebug() << url; 

      for (int i = 0; i < str.size(); ++i){ 
       if(str.at(i).contains("id=\"mainImg\"", Qt::CaseInsensitive)){ 

        pic = str.at(i); 
        pic = pic.remove(QRegExp("<img[^>]*src=['|\"]", Qt::CaseInsensitive)); 
        pic = pic.remove(QString::fromStdString("//"), Qt::CaseInsensitive); 
        pic = pic.remove('"'); 
        pic = pic.remove("'"); 
        pic = pic.remove('<'); 
        pic = pic.remove('>'); 
        pic = pic.remove(';'); 
        pic = pic.left(pic.length()-1); 
        //qDebug() << str.at(i); 
        //qDebug() << pic; 
       } 
      } 
     }else{ 
      pic = ""; 
     } 
     //qDebug() << "Lines: " << str.size(); 

    }else{ 
     pic = ""; 
    } 
    return pic; 
} 

qdownload.cpp

#include "qdownloader.h" 

QDownloader::QDownloader(QObject *parent) : 
    QObject(parent) 
{ 
    manager = new QNetworkAccessManager; 
} 

QDownloader::~QDownloader() 
{ 
    manager->deleteLater(); 
} 

void QDownloader::setFile(QString fileURL, QString folderName, QString fileName) 
{ 

    QDir dir; 
    if(dir.exists(folderName)){ 
     //qDebug() << "Existis: " + folderName; 
    }else{ 
     dir.mkdir(folderName); 
     //() << "Created: " + folderName; 
    } 

    QString filePath = fileURL; 
    QStringList filePathList = filePath.split('/'); 
    QString fileExt = filePathList.at(filePathList.count() - 1); 
    fileExt = "jpg"; 
    QString saveFilePath; 
    saveFilePath = QString(folderName + "/" + fileName + "." + fileExt); 



    QNetworkRequest request; 
    request.setUrl(QUrl(fileURL)); 
    reply = manager->get(request); 



    file = new QFile; 
    file->setFileName(saveFilePath); 


    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(onDownloadProgress(qint64,qint64))); 
    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(onFinished(QNetworkReply*))); 
    connect(reply,SIGNAL(readyRead()),this,SLOT(onReadyRead())); 
    connect(reply,SIGNAL(finished()),this,SLOT(onReplyFinished())); 
} 

void QDownloader::onDownloadProgress(qint64 bytesRead,qint64 bytesTotal) 
{ 
    qDebug(QString::number(bytesRead).toLatin1() +" - "+ QString::number(bytesTotal).toLatin1()); 
} 

void QDownloader::onFinished(QNetworkReply * reply) 
{ 
    switch(reply->error()) 
    { 
     case QNetworkReply::NoError: 
     { 
      qDebug("file is downloaded successfully."); 
     }break; 
     default:{ 
      qDebug(reply->errorString().toLatin1()); 
     }; 
    } 

    if(file->isOpen()) 
    { 
     file->close(); 
     file->deleteLater(); 
    } 
} 

void QDownloader::onReadyRead() 
{ 
    qDebug() << "Ready"; 
    file->open(QIODevice::WriteOnly); 
    file->write(reply->readAll()); 
} 

void QDownloader::onReplyFinished() 
{ 
    if(file->isOpen()) 
    { 
     file->close(); 
     file->deleteLater(); 
    } 
} 
+0

@lpapp, пожалуйста, проверьте это дважды. Я не думаю, что это ответит на этот вопрос. – mhcuervo

+0

@ mhcuervo: Я вновь открыл это для вашего удовольствия, но это было пограничной линией в моем скромном мнении. – lpapp

ответ

2

Я подготовил очень простой пример, который вы можете использовать в качестве ссылки.

В каком-то месте в «мой» загрузчик я запускаю запрос:

QNetworkRequest request; 
request.setUrl(org); 
_reply = _manager->get(request); // Manager is my QNetworkAccessManager 
connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), 
      this, SLOT(error(QNetworkReply::NetworkError))); 
connect(_reply, SIGNAL(downloadProgress(qint64, qint64)), 
      this, SLOT(updateProgress(qint64, qint64))); 
connect(_reply, SIGNAL(finished()), 
      this, SLOT(finished())); 

Как вы можете видеть все, что вам нужно сделать, это get() и правильно использовать сигналы QNetworkReply. После «мои» Слоты:

void MyDownloader::error(QNetworkReply::NetworkError err) 
{ 
    // Manage error here. 
    _reply->deleteLater(); 
} 

void MyDownloader::updateProgress(qint64 read, qint64 total) 
{ 
    // This is where you can use the progress info for, lets say, update a progress bar: 
    // progressBar->setMaximum(total); 
    // progressBar->setValue(read); 
} 

void MyDownloader::finished() 
{ 
    // Save the image here 
    QByteArray b = _reply->readAll(); 
    QFile file(des); // "des" is the file path to the destination file 
    file.open(QIODevice::WriteOnly); 
    QDataStream out(&file); 
    out << b; 
    _reply->deleteLater(); 
    // done 
} 

Обратите внимание, что вы можете записать в файл в updateProgress() вместо того, чтобы писать весь файл сразу, когда ответ закончен.


Для написания на updateProgress(), открытой и/или создать QFile на get время. Затем используйте ответ readAll при каждом обновлении и напишите прочитанные данные в файл, затем закройте файл, когда finished.

// ... 
    _file = new QFile(des); 
    _reply = _manager->get(request); 
/// ... 

void MyDownloader::updateProgress(qint64 read, qint64 total) 
{ 
    QByteArray b = _reply->readAll(); 
    QDataStream out(_file); 
    out << b; 
} 

void MyDownloader::finished() 
{ 
    // Done 
    _reply->deleteLater(); 
    _file->close(); 
    // probably delete the file object too 
} 
+0

Как я могу написать файл в функции updateProgress()? – Talon06

+0

В запросе QNetworkRequest уже есть ответ = manager-> get (request); request.setUrl (QUrl (файлURL)); ответить = менеджер-> получить (запрос); – Talon06

+0

@ Talon06, я обновил ответ. – mhcuervo