使用 QLabel 加载图片并实现图片的自适应。
在讲述图片不被拉伸的实例之前,先看一个被任意拉伸的情况。
示例代码
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPixmap>
#include <QVBoxLayout>class MyWidget : public QWidget {QLabel *label;public:MyWidget(QWidget *parent = nullptr) : QWidget(parent) {label = new QLabel(this);QPixmap pixmap(":/images/sample.jpg");label->setPixmap(pixmap);label->setScaledContents(true); // 直接拉伸内容label->setAlignment(Qt::AlignCenter);QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(label);setLayout(layout);}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);MyWidget window;window.resize(400, 300);window.show();return app.exec();
}
上面的例子发现,图片在窗口尺寸发生变化后,图片随着 label
放大/缩小而放大/缩小,而不是等比例缩放。
使用 QLabel
的 pixmap
和 scaled
方法
可以重写控件的 resizeEvent
方法,当控件大小变化时,动态调整图片大小,保持比例不变。
示例代码
#include <QApplication>
#include <QLabel>
#include <QPixmap>
#include <QResizeEvent>class ScaledLabel : public QLabel {Q_OBJECTpublic:explicit ScaledLabel(QWidget *parent = nullptr) : QLabel(parent) {setScaledContents(false); // 禁用内容拉伸}void setPixmapWithAspectRatio(const QPixmap &pixmap) {originalPixmap = pixmap;updateScaledPixmap();}protected:void resizeEvent(QResizeEvent *event) override {QLabel::resizeEvent(event);updateScaledPixmap();}private:QPixmap originalPixmap;void updateScaledPixmap() {if (!originalPixmap.isNull()) {QSize labelSize = this->size();QPixmap scaled = originalPixmap.scaled(labelSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);QLabel::setPixmap(scaled);}}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);ScaledLabel label;QPixmap pixmap(":/example/image.png"); // 替换为你的图片路径label.setPixmapWithAspectRatio(pixmap);label.resize(400, 300); // 设置初始大小label.show();return app.exec();
}
关键点说明
setScaledContents(false)
:防止默认的拉伸行为。QPixmap::scaled
:- 使用
Qt::KeepAspectRatio
保持比例。 - 使用
Qt::SmoothTransformation
提高缩放后的画质。
- 使用
resizeEvent
:- 动态调整图片大小,当控件大小变化时,触发重新计算图片尺寸。
效果
- 图片会根据控件的大小自动调整,但始终保持宽高比例不变。
- 图片不会被拉伸变形,只会按比例缩放以适用控件。