Я пытался использовать класс AspectRatioPixmapLabel
в phyatt, но столкнулся с несколькими проблемами:
- Иногда мое приложение входило в бесконечный цикл событий изменения размера.Я проследил это до вызова
QLabel::setPixmap(...)
внутри метода resizeEvent, потому что QLabel
фактически вызывает updateGeometry
внутри setPixmap
, что может вызывать события изменения размера ... heightForWidth
, казалось, былоигнорируется содержащим виджет (a QScrollArea
в моем случае), пока я не начал устанавливать политику размера для метки, явно вызывая policy.setHeightForWidth(true)
- Я хочу, чтобы метка никогда не увеличивалась больше, чем исходный размер растрового изображения
QLabel
Реализация minimumSizeHint()
делает некоторую магию для меток, содержащих текст, но всегда сбрасывает политику размера к политике по умолчанию, поэтому мне пришлось перезаписать ее
сказал, вот мое решение.Я обнаружил, что могу просто использовать setScaledContents(true)
и позволить QLabel
обрабатывать изменение размера.Конечно, это зависит от содержащегося виджета / макета, соблюдающего 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_H
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();
}
}