Easiest way to display images on the Internet



  • Recently I am making Mastodon's client application.
    So I would like to display the avatar image on the Internet,
    but I do not know its easiest way.

    My idea is to download the image locally and then display it.
    Is this easiest way?
    Is there any other easier way?


  • Moderators

    @wabisuke2718 You could use http://doc.qt.io/qt-5/qtwebview-index.html with HTML and embed the URL to the picture.



  • Yes, download image with QNetworkAccesManager, load QImage from memory using QImage::loadFromData or QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR) constructor, then display it with QPainter or in QLabel.
    @jsulm said in Easiest way to display images on the Internet:

    @wabisuke2718 You could use http://doc.qt.io/qt-5/qtwebview-index.html with HTML and embed the URL to the picture.

    Using QWebView for this is an overkill.



  • Also, since QNetworkReply is QIODevice descendant, you can just use qimage.load(networkReply, nullptr) when QNetworkAccessManager::finished signal is emitted.



  • I wrote this code.
    But avatar images disappears immediately after the default image is displayed.

    iconwidget.h

    #ifndef ICONWIDGET_H
    #define ICONWIDGET_H
    
    #include <QWidget>
    #include <QPaintEvent>
    #include <QImage>
    
    #include <QNetworkAccessManager>
    #include <QUrl>
    
    class IconWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit IconWidget(QUrl *iconUrl, QWidget *parent = 0);
        QSize sizeHint() const override;
        QNetworkAccessManager *manager;
    
    protected:
        void paintEvent(QPaintEvent *);//←ここ重要!ペイントイベント
    
    private:
        QImage *iconImage = nullptr;
    
    signals:
    
    public slots:
    
    private slots:
        void replyFinished(QNetworkReply* reply);
    };
    
    #endif // ICONWIDGET_H
    
    

    iconwidget.cpp

    #include "iconwidget.h"
    #include <QPainter>
    #include <QImage>
    #include <QNetworkReply>
    
    #include <QDebug>
    
    IconWidget::IconWidget(QUrl *iconUrl, QWidget *parent) : QWidget(parent)
    {
        qDebug() << "IconWidget::IconWidget() called.";
    
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    
        setStyleSheet("IconWidget { border: 1px solid; }");
        setMaximumSize(50, 50);
    
        //manager = new QNetworkAccessManager(this);
        QNetworkRequest request;
        //request.setUrl(QUrl("http://zwjte.com/s/media/images/35ea10fc43.jpg"));
        request.setUrl(*iconUrl);
        /*reply = */manager->get(request);
        //connect(reply, SIGNAL(readyRead()), this, SLOT(ReadyRead()));
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    }
    
    void IconWidget::paintEvent(QPaintEvent *)//←重要!ペイントイベント
    {
        qDebug() << "IconWidget::paintEvent() called.";
    
        if (iconImage == nullptr) {
            qDebug() << "iconImage is null.";
    
            QPainter painter(this);
            painter.drawImage(0, 0, QImage("taiyo.jpg"));
    
        } else {
            qDebug() << "iconImage is not null.";
    
            QPainter painter(this);
    
            //QImage *iconImage = new QImage("taiyo.jpg");
            //iconImage->scaledToWidth(50, Qt::KeepAspectRatio);
            //iconImage->scaled(10, 10, Qt::KeepAspectRatio);
    
            painter.setRenderHint(QPainter::Antialiasing, true);
            //painter.drawImage(0, 0, QImage("taiyo.jpg"));
            //painter.drawImage(0, 0, *iconImage);
            painter.drawImage(0, 0, iconImage->scaled(50, 50, Qt::KeepAspectRatio));
        }
    
        qDebug() << "IconWidget::paintEvent() end.";
    }
    
    QSize IconWidget::sizeHint() const
    {
        qDebug() << "IconWidget::sizeHint() called.";
        return QSize(50, 50);
    }
    
    void IconWidget::replyFinished(QNetworkReply *reply)
    {
        qDebug() << "IconWidget::replyFinished() called.";
    
        iconImage = new QImage();
        iconImage->load(reply, nullptr);
        //iconImage->loadFromData(reply->readAll());
        this->repaint();
    
        qDebug() << "IconWidget::replyFinished() end.";
    }
    
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    #include <QNetworkAccessManager>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        QNetworkAccessManager *manager;
    
    private slots:
        void on_getTootButton_clicked();
        void replyFinished(QNetworkReply* reply);
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QLabel>
    #include <QFrame>
    
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    
    #include <QJsonObject>
    #include <QJsonDocument>
    #include <QJsonParseError>
    #include <QJsonArray>
    
    #include <vector>
    
    #include "iconwidget.h"
    #include <QHBoxLayout>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_getTootButton_clicked()
    {
        manager->get(QNetworkRequest(QUrl("https://mstdn.jp/api/v1/timelines/public?local=\"true\"")));
    }
    
    void MainWindow::replyFinished(QNetworkReply *reply)
    {
        qDebug() << "replyFinished() called.";
    
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray byteArray = reply->readAll();
            //ui->textEdit->setPlainText(byteArray);
    
            QJsonParseError error;
            QJsonDocument jsonDocument = QJsonDocument::fromJson(byteArray, &error);
            qDebug() << error.errorString();
    
            /*
            qDebug() << "Is Object? " << jsonDocument.isObject();
            qDebug() << "Is Array? " << jsonDocument.isArray();
            */
    
            QJsonArray jsonArray = jsonDocument.array();
            //qDebug() << jsonArray.size();
            QStringList keys = jsonArray[0].toObject().keys();
            qDebug() << keys;
            foreach (QString key, keys) {
                qDebug() << "key =" << key;
                QString value = jsonArray[0].toObject().value(key).toString();
                qDebug() << "value =" << value;
            }
    
            //QJsonObject jsonObject = jsonDocument.object();
    
            //qDebug() << jsonObject.empty();
    
            /*
            QStringList keys = jsonObject.keys();
            qDebug() << keys;
            foreach (QString key, keys) {
                qDebug() << "key =" << key;
                QString value = jsonObject.value(key).toString();
                qDebug() << "value =" << value;
            }
            */
    
            /*
            QStringListModel *model = new QStringListModel();
            QStringList qlist;
            qlist << "ONE\nKAIGYO";
            qlist << "TWO";
            qlist << "THREE";
            model->setStringList(qlist);
            ui->tootList->setModel(model);
            */
    
            /*
            QStringListModel *model = new QStringListModel();
            QStringList qList;
            for (int i=0; i<jsonArray.size(); i++) {
                QString tootHtml = jsonArray[i].toObject().value("content").toString();
                QRegExp br("<br />");
                tootHtml.replace(br, "\n");
                QRegExp tag("<[^>]*>");
                tootHtml.remove(tag);
                qList << tootHtml;
            }
            model->setStringList(qList);
            ui->tootList->setModel(model);
            */
    
            //std::vector<QHBoxLayout*> tootLayouts;
            static QVBoxLayout *timelineLayout = new QVBoxLayout();
            //for (int i=0; i<jsonArray.size(); i++) {
            for (int i=jsonArray.size()-1; i>=0; i--) {
                QFrame *tootFrame = new QFrame();
                tootFrame->setObjectName("tootFrame");
                tootFrame->setStyleSheet("#tootFrame { border: 1px solid; background-color: white; }");
                //tootFrame->maximumWidth = ui->scrollAreaWidgetContents->width();
                //tootFrame->setMaximumWidth(ui->scrollAreaWidgetContents->width());
                QHBoxLayout *tootLayout = new QHBoxLayout();
    
                QVBoxLayout *tootContentsLayout = new QVBoxLayout();
                QLabel *name = new QLabel(jsonArray[i].toObject().value("account").toObject().value("display_name").toString(), this);
    
                QString tootHtml = jsonArray[i].toObject().value("content").toString();
                QRegExp br("<br />");
                tootHtml.replace(br, "\n");
                QRegExp tag("<[^>]*>");
                tootHtml.remove(tag);
                QLabel *toot = new QLabel(tootHtml);
                toot->setWordWrap(true);
    
                QUrl *iconUrl = new QUrl(jsonArray[i].toObject().value("account").toObject().value("avatar").toString());
                IconWidget *iconWidget = new IconWidget(iconUrl, nullptr);
                tootLayout->addWidget(iconWidget);
    
                tootContentsLayout->addWidget(name);
                tootContentsLayout->addWidget(toot);
                tootLayout->addLayout(tootContentsLayout);
                tootFrame->setLayout(tootLayout);
    
                //timelineLayout->addLayout(tootLayout);
                //timelineLayout->addWidget(tootFrame);
                timelineLayout->insertWidget(0, tootFrame);
            }
            //ui->tootList->setLayout(timelineLayout);
            ui->scrollAreaWidgetContents->setLayout(timelineLayout);
    
            /*
            QHBoxLayout tootLayout;
            QVBoxLayout *tootContentsLayout = new QVBoxLayout(this);
            QLabel toot("あいうえお\nかきくけこ\nさしすせそ");
            QLabel *name = new QLabel("やみとも", this);
            tootContentsLayout->addWidget(name);
            tootContentsLayout->addWidget(&toot);
            //tootLayout.addLayout(tootContentsLayout);
            //ui->tootList->setLayout(&tootLayout);
            ui->tootList->setLayout(tootContentsLayout);
            //ui->tootList->update();
            */
        }
    }
    
    


  • Solved!
    The problem was calling same connect function twice.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.