Я спробував використати AspectRatioPixmapLabelклас phyatt's , але зазнав декількох проблем:
- Іноді мій додаток потрапляв у нескінченний цикл подій зміни розміру. Я простежив це назад до виклику
QLabel::setPixmap(...)всередині методу resizeEvent, оскільки QLabelнасправді виклики updateGeometryвсередині setPixmap, що може викликати події зміни розміру ...
heightForWidthздавалося, ігнорується вміщуючим віджетом ( 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();
}
}