在Qt中显示图像以适合标签尺寸

时间:2011-04-13 17:24:44

标签: image qt autoresize

我已经尝试了几种在表单上显示图像的方法,但它们都没有按照我的意愿运行。

我读过许多地方,最简单的方法是创建标签并使用它来显示图像。我有一个标签,其大小由布局指定,但如果我用像素图加载图像,标签将调整大小为图像的大小。如果我使用img标签作为text或css background属性,它将不会显示整个图像。我想要做的是加载图像并适应标签,而不是更改标签的大小,但是当我调整窗口大小时,以及调整标签大小时,图像也应调整大小以使其始终适合进入它。

如果唯一的方法是获取标签的大小,并调整像素图以适应它,并处理调整大小事件(信号),我怎么能调整像素图的大小?我希望我不需要将整个事物保存到QImage中,并且每次都从它创建一个像素图。

另外,我该如何居中呢?如果它不能同时适合宽度和高度,我希望较小的尺寸居中。

哦,我不想使用滑块来处理溢出。

7 个答案:

答案 0 :(得分:18)

QLabel::setScaledContents(bool)有帮助吗? image viewer example也可能有一些有用的信息。

答案 1 :(得分:18)

实际上这个问题有一个非常简单的解决方案。您应该修改两件事:

  1. 将缩放内容设置为true(如上所述)
  2. 将标签的尺寸政策设为忽略

    QLabel lblImage;
    
    lblImage->setPixmap( QPixmap( "big_image.jpg" ) );
    
    lblImage->setScaledContents( true );
    
    lblImage->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
    
  3. 如果lblImage自动调整大小,图像将拉伸到标签的大小。

答案 2 :(得分:14)

我也会回答我自己的问题,但不会将其标记为解决方案,因为我要求上面给出一个简单的问题。毕竟我最终使用了一个不太简单的解决方案,所以任何需要做类似事情并且有时间在这里玩的人都是我的最终工作代码。我们的想法是扩展QLabel并重载setPixmap和drawEvent方法。

QPictureLabel.hpp (标题文件)

#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 (实施)

#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);
}

用法:与使用普通标签显示图片wirthout 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);

答案 3 :(得分:10)

保留原始pixmap的副本。然后将resized信号连接到实现此目的的插槽(或覆盖resizeEvent()函数):

lblImage->setPixmap(pixmap.scaled(lblImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));

答案 4 :(得分:2)

ui->label->setPixmap( pix.scaled( ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation) );

在我的案子中(Qt 5.11)像魅力一样工作。 pix是具有原始像素数的QPixmap对象(例如,用QPixmap::fromImage(path)构造)。

答案 5 :(得分:0)

在Qt Designer中,您必须设置两项:

  1. 将像素图设置为所需的图像
  2. 检查 scaledContents

如下图所示:

enter image description here

在这里,底部的标签被 scaledContents 选中,顶部的标签未被选中。

enter image description here

答案 6 :(得分:0)

QPixmap pic = QPixmap(":/resource/xxx.png").scaled(16,16,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

ui->yourLable->setPixmap(pic);