Я спробував використати 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();
}
}