Получить изображение с сайта

      Комментарии к записи Получить изображение с сайта отключены

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 12 мес. назад.

  • Автор
    Сообщения
  • #3000

    Если изображение расположено на вашем компьютере, то вы можете сразу его использовать:

    QLabel label;
    label.setPixmap(QPixmap(path));
    label.show()

    Этот пример отобразит картинку, расположенную по пути path. Однако, если изображение расположено на каком-либо удаленном ресурсе (например сайте) — его необходимо сначала скачать оттуда.

    Очевидно, нам нужен класс, выполняющий загрузку картинки, у него должен быть конструктор и функция (слот) запроса картинки. После того, как данные получены результат мы бы хотели получать при помощи сигнала. При возникновении ошибки загрузки мы бы хотели получать исключение [2].

    Для получения данных с сайта в библиотеке Qt используется класс QNetworkAccessManager — мы уже рассматривали его: Разработка парсера сайта на C++, Qt [1]. Экземпляр QNetworkAccessManager должен являться членом нашего класса-загрузчика, т.к. в функции load() нам нужно будет передать ему запрос на получение данных с сайта, а в конструкторе — связать с сигналом finished() слот on_load(). Функция on_load() не относится к интерфейсу класса, т.к. ее нет смысла вызывать никакому клиентскому коду — ее есть смысл поместить в секцию private:

    #ifndef PIXMAPLOADER_H
    #define PIXMAPLOADER_H
    
    #include <qnetworkaccessmanager>
    #include <qpixmap>
    
    class PixmapLoader : public QObject {
        Q_OBJECT
    public:
        PixmapLoader(QObject *parent = 0);
    
        struct NetworReplyException : public std::invalid_argument{
            NetworReplyException(std::string what) : std::invalid_argument(what) {
            }
        };
    public slots:
        void load(QString imageUrl);
    private slots:
        void on_load(QNetworkReply* reply);
    signals:
        void loaded(QPixmap);
    private:
        QNetworkAccessManager m_manager;
    };
    
    #endif // PIXMAPLOADER_H

    #include "pixmaploader.h"
    #include <qurl>
    #include <qnetworkrequest>
    #include <qnetworkreply>
    
    PixmapLoader::PixmapLoader(QObject *parent) :
        QObject(parent) {
        connect(&m_manager, SIGNAL(finished(QNetworkReply*)), SLOT(on_load(QNetworkReply*)));
    }
    
    void PixmapLoader::load(QString imageUrl) {
        m_manager.get(QNetworkRequest(QUrl(imageUrl)));
    }
    
    void PixmapLoader::on_load(QNetworkReply *reply) {
        if(reply->error() != QNetworkReply::NoError)
            throw NetworReplyException("in PixmapLoader: " + reply->errorString().toStdString());
    
        QPixmap pixmap;
        pixmap.loadFromData(reply->readAll());
    
        emit loaded(pixmap);
        reply->deleteLater();
    }

    Для демонстрации, создадим экземпляры QLabel и PixmapLoader, свяжем их сигналы и слоты:

    int main(int argc, char *argv[]) {
        QApplication a(argc, argv);
    
        QLabel label;
        PixmapLoader pixmapLoader;
    
        QObject::connect(&pixmapLoader, SIGNAL(loaded(QPixmap)),
                         &label, SLOT(setPixmap(QPixmap)));
    
        pixmapLoader.load("https://pro-prof.com/wp-content/uploads/2016/07/sequence-diagram-par-section.png");
    
        label.show();
        return a.exec();
    }

    Результат приведен на снимке экрана (загружается изображение с одной из моих статей, посвященной диаграммам UML):

    QPixmapLoader-remote-example

    Вспомогательная литература:

    1. Разработка парсера сайта на C++, Qt — описывается использование класса QNetworkAccessManager для разработки парсера биржи фриланса. Там же рассказывается про паттерн Producer/Consumer и параллельное программирование в Qt;
    2. Заметка про обработку исключений — описывается как работают исключения, проводится их сравнение с другими способами обработки ошибок и приводятся рекомендации по их правильному использованию;
    3. Основы UML. Диаграммы последовательности — описываются диаграммы последовательности UML и их место в процессе проектирования ICONIX.

Для ответа в этой теме необходимо авторизоваться.