Я пробовал использовать AspectRatioPixmapLabel
класс phyatt , но столкнулся с несколькими проблемами:
- Иногда мое приложение входило в бесконечный цикл событий изменения размера. Я проследил это до вызова
QLabel::setPixmap(...)
внутри метода resizeEvent, потому что на QLabel
самом деле вызывает updateGeometry
внутри setPixmap
, что может запускать события изменения размера ...
heightForWidth
казалось, игнорируется содержащим виджетом (a QScrollArea
в моем случае), пока я не начал устанавливать политику размера для метки, явно вызываяpolicy.setHeightForWidth(true)
- Я хочу, чтобы размер метки никогда не превышал исходный размер растрового изображения
QLabel
реализация minimumSizeHint()
делает некоторую магию для меток, содержащих текст, но всегда сбрасывает политику размера на значение по умолчанию, поэтому мне пришлось перезаписать ее
Тем не менее, вот мое решение. Я обнаружил, что могу просто использовать setScaledContents(true)
и позволить QLabel
изменять размер. Конечно, это зависит от содержащегося в нем виджета / макета, поддерживающего heightForWidth
.
аспектratiopixmaplabel.h
#ifndef ASPECTRATIOPIXMAPLABEL_H
#define ASPECTRATIOPIXMAPLABEL_H
#include <QLabel>
#include <QPixmap>
class AspectRatioPixmapLabel : public QLabel
{
Q_OBJECT
public:
explicit AspectRatioPixmapLabel(const QPixmap &pixmap, QWidget *parent = 0);
virtual int heightForWidth(int width) const;
virtual bool hasHeightForWidth() { return true; }
virtual QSize sizeHint() const { return pixmap()->size(); }
virtual QSize minimumSizeHint() const { return QSize(0, 0); }
};
#endif
аспектratiopixmaplabel.cpp
#include "aspectratiopixmaplabel.h"
AspectRatioPixmapLabel::AspectRatioPixmapLabel(const QPixmap &pixmap, QWidget *parent) :
QLabel(parent)
{
QLabel::setPixmap(pixmap);
setScaledContents(true);
QSizePolicy policy(QSizePolicy::Maximum, QSizePolicy::Maximum);
policy.setHeightForWidth(true);
this->setSizePolicy(policy);
}
int AspectRatioPixmapLabel::heightForWidth(int width) const
{
if (width > pixmap()->width()) {
return pixmap()->height();
} else {
return ((qreal)pixmap()->height()*width)/pixmap()->width();
}
}