Display image in Qt to fit label size

前端 未结 7 1275
[愿得一人]
[愿得一人] 2021-02-01 02:53

I already tried several methods on displaying an image on a form, but none of them works how I would like.

I\'ve read many places that the easiest way is to create a la

7条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-01 03:36

    I will also answer my own question, but won't mark it as solution, because I requested a simple one which was given above. I ended up using a not too simple solution after all, so anyone who also needs to do something similar and has the time to play with it here's my final working code. The idea is to expand the QLabel and overload the setPixmap and the drawEvent methods.

    QPictureLabel.hpp (header file)

    #include "QImage.h"
    #include "QPixmap.h"
    #include "QLabel.h"
    
    class QPictureLabel : public QLabel
    {
    private:
        QPixmap _qpSource; //preserve the original, so multiple resize events won't break the quality
        QPixmap _qpCurrent;
    
        void _displayImage();
    
    public:
        QPictureLabel(QWidget *aParent) : QLabel(aParent) { }
        void setPixmap(QPixmap aPicture);
        void paintEvent(QPaintEvent *aEvent);
    };
    

    QPictureLabel.cpp (implementation)

    #include "QPainter.h"
    
    #include "QPictureLabel.hpp"
    
    void QPictureLabel::paintEvent(QPaintEvent *aEvent)
    {
        QLabel::paintEvent(aEvent);
        _displayImage();
    }
    
    void QPictureLabel::setPixmap(QPixmap aPicture)
    {
        _qpSource = _qpCurrent = aPicture;
        repaint();
    }
    
    void QPictureLabel::_displayImage()
    {
        if (_qpSource.isNull()) //no image was set, don't draw anything
            return;
    
        float cw = width(), ch = height();
        float pw = _qpCurrent.width(), ph = _qpCurrent.height();
    
        if (pw > cw && ph > ch && pw/cw > ph/ch || //both width and high are bigger, ratio at high is bigger or
            pw > cw && ph <= ch || //only the width is bigger or
            pw < cw && ph < ch && cw/pw < ch/ph //both width and height is smaller, ratio at width is smaller
            )
            _qpCurrent = _qpSource.scaledToWidth(cw, Qt::TransformationMode::FastTransformation);
        else if (pw > cw && ph > ch && pw/cw <= ph/ch || //both width and high are bigger, ratio at width is bigger or
            ph > ch && pw <= cw || //only the height is bigger or
            pw < cw && ph < ch && cw/pw > ch/ph //both width and height is smaller, ratio at height is smaller
            )
            _qpCurrent = _qpSource.scaledToHeight(ch, Qt::TransformationMode::FastTransformation);
    
        int x = (cw - _qpCurrent.width())/2, y = (ch - _qpCurrent.height())/2;
    
        QPainter paint(this);
        paint.drawPixmap(x, y, _qpCurrent);
    }
    

    Usage : the same as using a normal label for displaying image wirthout the setScaledContents

    img_Result = new QPictureLabel(ui.parent);
    layout = new QVBoxLayout(ui.parent);
    layout->setContentsMargins(11, 11, 11, 11);
    ui.parent->setLayout(layout);
    layout->addWidget(img_Result);
    
    //{...}
    
    QPixmap qpImage(qsImagePath);
    img_Result->setPixmap(qpImage);
    

提交回复
热议问题