如何在Qt中调整图像大小?

cha*_*m15 13 c++ qt

我创建了一个名为ImageLabel的类,它扩展了QLabel.我希望它保持显示的图像的大小比例,无论它是多么伸展.当你使窗户变大时,它工作正常.当你试图让窗口变小时,问题出现了:它没有调整高度,它会让它伸展开来.我该如何解决?


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

Run Code Online (Sandbox Code Playgroud)

jdi*_*jdi 15

有几种方法可以做到这一点,但最重要的是我建议也许不要通过试图提示方面来对抗布局系统.如您所见,您必须尝试实现一些尝试帮助布局的方法.

我可以提供两个例子.他们都没有使用布局......

第一个使用子项QLabel来显示图像,并从resize事件中驱动其固定大小:

// 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);
}
Run Code Online (Sandbox Code Playgroud)

第二个例子是基于@Arnold_Spence给出的答案.它更短,因为它不使用儿童QLabel.它只是在paint事件中绘制像素图:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

  • 澄清一下,这两个都对我有用,但只有在我对实例也这样做之后(在 pyQt 中):`imageLabelSizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding); imageLabelSizePolicy.setHeightForWidth(True); imageLabel.setSizePolicy(imageLabelSizePolicy)`。这可能是 Qt n00b 的评论,但我相信在未来的某个时候,另一个 Qt n00b 会出现在此页面上。 (2认同)