我创建了一个名为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();
}
答案 0 :(得分:15)
有几种方法可以做到这一点,但最重要的是我建议也许不要通过试图提示方面来对抗布局系统。正如您所看到的,您必须尝试实现一些尝试帮助布局的方法。
我可以提供两个例子。他们都没有使用布局......
第一个使用子QLabel
来显示图像,并从调整大小事件中驱动其固定大小:
// 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);
}
第二个例子是基于@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;
}
答案 1 :(得分:2)
QLabel
内置了无法维护图像宽高比的功能。由于Qlabel
可能具有您不需要的功能,因此您应该继承QWidget
并覆盖paintEvent()
以按照您希望的方式呈现图像。