Intenté usar la AspectRatioPixmapLabelclase de phyatt , pero experimenté algunos problemas:
- A veces, mi aplicación entraba en un ciclo infinito de eventos de cambio de tamaño.
QLabel::setPixmap(...)Rastreé esto hasta la llamada de dentro del método resizeEvent, porque en QLabelrealidad las llamadas updateGeometrydentro setPixmap, lo que puede desencadenar eventos de cambio de tamaño ...
heightForWidthparecía ser ignorado por el widget contenedor (a QScrollAreaen mi caso) hasta que comencé a configurar una política de tamaño para la etiqueta, llamando explícitamentepolicy.setHeightForWidth(true)
- Quiero que la etiqueta nunca crezca más que el tamaño del mapa de píxeles original
QLabelLa implementación de minimumSizeHint()hace algo de magia para las etiquetas que contienen texto, pero siempre restablece la política de tamaño a la predeterminada, así que tuve que sobrescribirla
Dicho esto, aquí está mi solución. Descubrí que podía usar setScaledContents(true)y dejar QLabelmanejar el cambio de tamaño. Por supuesto, esto depende del widget / diseño que lo contenga respetando el heightForWidth.
Aspectratiopixmaplabel.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
Aspectratiopixmaplabel.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();
}
}