Próbowałem użyć AspectRatioPixmapLabelklasy Phyatta , ale napotkałem kilka problemów:
- Czasami moja aplikacja wchodziła w nieskończoną pętlę zdarzeń zmiany rozmiaru. Prześledziłem to z powrotem do wywołania
QLabel::setPixmap(...)wewnątrz metody resizeEvent, ponieważ w QLabelrzeczywistości wywołania updateGeometrywewnątrz setPixmap, co może wywołać zdarzenia zmiany rozmiaru ...
heightForWidthwydawało się być ignorowane przez widżet zawierający (a QScrollAreaw moim przypadku), dopóki nie zacząłem ustawiać polityki rozmiaru dla etykiety, wyraźnie wywołującpolicy.setHeightForWidth(true)
- Chcę, aby etykieta nigdy nie rozrosła się bardziej niż oryginalny rozmiar piksmapy
QLabelImplementacja minimumSizeHint()robi trochę magii dla etykiet zawierających tekst, ale zawsze resetuje politykę rozmiaru do domyślnej, więc musiałem ją nadpisać
To powiedziawszy, oto moje rozwiązanie. Odkryłem, że mogę po prostu użyć setScaledContents(true)i pozwolić QLabelsobie na zmianę rozmiaru. Oczywiście zależy to od widżetu / układu zawierającego rozszerzenie heightForWidth.
aspektratiopixmaplabel.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
aspektratiopixmaplabel.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();
}
}