Intenté usar la AspectRatioPixmapLabel
clase 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 QLabel
realidad las llamadas updateGeometry
dentro setPixmap
, lo que puede desencadenar eventos de cambio de tamaño ...
heightForWidth
parecía ser ignorado por el widget contenedor (a QScrollArea
en 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
QLabel
La 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 QLabel
manejar 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();
}
}