Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
525 views
in Technique[技术] by (71.8m points)

c++ - How do I make an image resize to scale in Qt?

I made a class called ImageLabel which extends QLabel. I want it to keep the size ratio of the image that it is displaying no matter how stretched out it is. It works fine when you make the window larger. The problem comes in when you try to make the window smaller: it doesnt resize the height, it leaves it stretched out. How do I fix this?


int ImageLabel::heightForWidth(int width) const {
    int height = (this->size.height()*width)/this->size.width();
    return height;
}

QSize ImageLabel::sizeHint() const {
    return this->size;
}

QSize ImageLabel::minimumSizeHint() const {
    return QSize(0, 0);
}

void ImageLabel::setSizePolicy(){
    QSizePolicy policy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    policy.setHeightForWidth(true);
    QLabel::setSizePolicy(policy);
    QLabel::setScaledContents(true);
}

void ImageLabel::setPixmap ( const QPixmap &pixmap ){
    this->size = pixmap.size();
    QLabel::setPixmap(pixmap);
}

int main(int argc, char *argv[]){
    QApplication a(argc, argv);

    QFrame *frame = new QFrame;
    QVBoxLayout *layout = new QVBoxLayout;
    frame->setLayout(layout);

    QPixmap map;
    map.load("test.png");
    ImageLabel *label = new ImageLabel;
    label->setSizePolicy();
    label->setPixmap(map);
    layout->addWidget(label);
    frame->show();

    return a.exec();
}

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are a couple ways to do this, but most of all I would recommend maybe not fighting against the layout system by trying to hint the aspect. As you can see, you are having to try and implement a number methods trying to help the layout.

I can offer two examples. Neither of them use layouts...

The first uses a child QLabel to show the image, and drives its fixed size off of the resize event:

// imagelabel.h

class ImageLabel : public QWidget
{
    Q_OBJECT

public:
    explicit ImageLabel(QWidget *parent = 0);
    const QPixmap* pixmap() const;

public slots:
    void setPixmap(const QPixmap&);

protected:
    void resizeEvent(QResizeEvent *);

private slots:
    void resizeImage();

private:
    QLabel *label;
};

// imagelabel.cpp

ImageLabel::ImageLabel(QWidget *parent) :
    QWidget(parent)
{
    label = new QLabel(this);
    label->setScaledContents(true);
    label->setFixedSize(0,0);
}

void ImageLabel::resizeEvent(QResizeEvent *event) {
    QWidget::resizeEvent(event);
    resizeImage();
}

const QPixmap* ImageLabel::pixmap() const {
    return label->pixmap();
}

void ImageLabel::setPixmap (const QPixmap &pixmap){
    label->setPixmap(pixmap);
    resizeImage();
}

void ImageLabel::resizeImage() {
    QSize pixSize = label->pixmap()->size();
    pixSize.scale(size(), Qt::KeepAspectRatio);
    label->setFixedSize(pixSize);
}

The second example is based off of the answer given by @Arnold_Spence. It is even shorter as it doesn't use a child QLabel. It just draws the pixmap in the paint event:

// imagelabel2.h

class ImageLabel2 : public QWidget
{
    Q_OBJECT

public:
    explicit ImageLabel2(QWidget *parent = 0);
    const QPixmap* pixmap() const;

public slots:
    void setPixmap(const QPixmap&);

protected:
    void paintEvent(QPaintEvent *);

private:
    QPixmap pix;
};

// imagelabel2.cpp

ImageLabel2::ImageLabel2(QWidget *parent) :
    QWidget(parent)
{
}

void ImageLabel2::paintEvent(QPaintEvent *event) {
    QWidget::paintEvent(event);

    if (pix.isNull())
        return;

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QSize pixSize = pix.size();
    pixSize.scale(event->rect().size(), Qt::KeepAspectRatio);

    QPixmap scaledPix = pix.scaled(pixSize,
                                   Qt::KeepAspectRatio,
                                   Qt::SmoothTransformation
                                   );

    painter.drawPixmap(QPoint(), scaledPix);

}

const QPixmap* ImageLabel2::pixmap() const {
    return &pix;
}

void ImageLabel2::setPixmap (const QPixmap &pixmap){
    pix = pixmap;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...