марта 20 2010
Версия для печати

Скачиваем файл с Qt4

Что он за чувства чувствовал внутри,
Пока Мума пускала пузыри?
Он привязал к Муме два кирпича —
Глаза садиста, руки палача.
© «Несчастный случай» о Trolltech и QHttp

Пишу курсовую с использованием замечательной кросс-платформенной библиотеки — Qt. Помимо того, что она кросс-платформена, что само по себе для меня очень удобно — нет необходимости запускать win даже под виртуалкой для разработки курсовой,  а собрать win32-версию необходимо, условие выполнения курсовой — приложение, исполняемое в среде win32. Так вот, помимо того, что Qt полностью кросс-платформена, она предлагает все средства для наиболее комфортной разработки приложений. Рекомендую.

Теперь к теме поста. Базовые функции уже реализовал, сейчас занимаюсь прикручиванием дополнительных и доработкой интерфейса. Захотелось мне в своей программе реализовать функционал, работающий с протоколом http, а точнее, выкачивающий некоторую информацию. Для этого сразу полез в QHttp, после продолжительной бесплодной возни с ним обнаружил, что в 4.6 он уже depreciated и скоро будет вообще удалён из Qt, а для работы с сетью теперь надлежит использовать кошерный QNetworkAccessManager.

Ну чтож, забил я на QHttp и полез в доки по QNetworkAccessManager, а когда вернулся, написал нижеследующий класс, полностью удовлетворяющий моим потребностям.

downloader.h

#ifndef DOWNLOADER_H
#define DOWNLOADER_H

#include <QObject>
#include <QNetworkReply>
#include <QFile>

class Downloader : public QObject
{
    Q_OBJECT

public:
    QNetworkReply *reply;
    QFile down;
    QNetworkAccessManager manager;
    void download(QUrl &url,QString fileName=""); //при вызове передаём функции url, откуда качать, и имя файла, куда сохранять

signals:
    void downloadDone();
    void downloadFailed();
    void saveFailed();

private slots:
    void saveFile();
    void replyFinished(QNetworkReply*);
};
#endif // DOWNLOADER_H

downloader.cpp

#include "downloader.h"
#include <QFileInfo>

void Downloader::download(QUrl &url, QString fileName)
{
    if (fileName.isEmpty())
    {
        if (QFileInfo(url.path()).fileName().isEmpty())
        {
            fileName="download.file";
        } else
        {
            fileName=QFileInfo(url.path()).fileName();
        }
    }
//если имя не передано (передано пустое), то пытаемся достать имя файла из url, в случае неудачи - обзываем "download.file"
    down.setFileName(fileName);
    if (!down.open(QIODevice::WriteOnly))
    {
        emit saveFailed();
        return;
    }
//проверяем на доступность файла для записи, открываем, иначе - генерируем сигнал ошибки, прерываем выполнение
    QNetworkRequest request(url);
    request.setUrl(url);
//формируем запрос
    reply=manager.get(request);
//отправляем запрос
    connect(&manager,SIGNAL(finished(QNetworkReply*)), this,SLOT(replyFinished(QNetworkReply*)));
    connect(reply,SIGNAL(readyRead()),this,SLOT(saveFile()));
//соединяем сигналы и слоты, при поступлении новых данных - вызывается слот saveFile(), при окончании передачи - replyFinished()
}

void Downloader::saveFile()
{
    down.write(reply->readAll());
//записываем полученные данные в файл
}
void Downloader::replyFinished(QNetworkReply *reply)
{
    if (reply->error())
        emit downloadFailed();
    else
        emit downloadDone();
//если передача завершилась ошибкой - генерируем сигнал ошибки, иначе - генерируем сигнал успешного окончания передачи
    down.close();
//закрываем файл
}

Генерируемые сигналы очень удобно использовать для вывода сообщений об ошибках.



Предлагаю почитать по теме:

  1. ОООП в примерах
  2. Librarian 0.1 alpha
  3. Librarian 0.2
  4. OSD в mocp при прослушивании интернет-радио
  5. Преферанс 1


Комментариев: 6

  1. Вот всё-таки хорошая манера, узнал что-то сам — напиши в блог) Но у тя это лучше чем у меня получается, так чётко всё) Мои посты в блог слишком эмоциональные и сумбурные)

  2. NEXUS, раз манера хорошая — буду продолжать в том же духе :)

    Спасибо на добром слове)

  3. Эт кст какой язык?

  4. S@nGoL, Ymilij пишет:

    Теги: C++, QHttp, QNetworkAccessManager, Qt, программирование

    Инкремент C это, как видишь ;)

  5. Anonymous
    27.04.2010 в 20:08

    Мило. Пешы ищщо.

  6. Anonymous, благодарю, обязательно ;)


Комментарии RSS Адрес для трекбека

Ваш комментарий