Próbowałem użyć AspectRatioPixmapLabel
klasy 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 QLabel
rzeczywistości wywołania updateGeometry
wewnątrz setPixmap
, co może wywołać zdarzenia zmiany rozmiaru ...
heightForWidth
wydawało się być ignorowane przez widżet zawierający (a QScrollArea
w 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
QLabel
Implementacja 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ć QLabel
sobie 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();
}
}