使用 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_OBJECT
public:
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
:- 动态调整图片大小,当控件大小变化时,触发重新计算图片尺寸。
效果
- 图片会根据控件的大小自动调整,但始终保持宽高比例不变。
- 图片不会被拉伸变形,只会按比例缩放以适用控件。