Я пробовал использовать 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();
}
}