Ответ 1
Помогает ли помощь QLabel:: setScaledContents (bool)? Также может быть некоторая полезная информация в примере просмотра изображений.
Я уже пробовал несколько методов отображения изображения в форме, но ни один из них не работает, как мне хотелось бы.
Я читал много мест, что самый простой способ - создать ярлык и использовать его для отображения изображения. У меня есть метка, размер которой указан макетом, но если я загружу изображение в него с помощью pixmap, метка будет изменена до размера изображения. Если я использую img tag как свойство text или css background, он не отображает изображение целиком. То, что я хотел бы сделать, - загрузить изображение и вставить его в метку, не изменяя размер метки, но когда я изменил размер моего окна и, изменив размер этикетки, изображение тоже должно быть изменено, чтобы оно всегда соответствовало в него.
Если единственным способом является получение размера метки и изменение размера pixmap, чтобы оно соответствовало, и обрабатывать событие изменения размера (сигнал), как я могу изменить размер pixmap? Надеюсь, мне не понадобится сохранять все это в QImage и каждый раз создавать с ним pixmap.
Кроме того, как я могу сосредоточить его? Если он не может соответствовать ширине и высоте, я хотел бы, чтобы меньший размер был центрирован.
О, и я не хочу использовать ползунки для обработки переполнения.
Помогает ли помощь QLabel:: setScaledContents (bool)? Также может быть некоторая полезная информация в примере просмотра изображений.
На самом деле есть очень простое решение этой проблемы. Вам нужно изменить две вещи:
Установите политику размера метки на игнорируемую
QLabel lblImage;
lblImage->setPixmap( QPixmap( "big_image.jpg" ) );
lblImage->setScaledContents( true );
lblImage->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
Если lblImage
автоматически изменяет размер, изображение растягивается до размера метки.
Я также отвечу на свой вопрос, но не буду отмечать его как решение, потому что я попросил простую, которая была приведена выше. В конце концов, я закончил тем, что использовал не слишком простое решение, поэтому всем, кто также должен сделать что-то подобное, и имеет время, чтобы сыграть с ним здесь мой последний рабочий код. Идея состоит в том, чтобы расширить QLabel и перегрузить методы setPixmap и drawEvent.
QPictureLabel.hpp (заголовочный файл)
#include "QImage.h"
#include "QPixmap.h"
#include "QLabel.h"
class QPictureLabel : public QLabel
{
private:
QPixmap _qpSource; //preserve the original, so multiple resize events won't break the quality
QPixmap _qpCurrent;
void _displayImage();
public:
QPictureLabel(QWidget *aParent) : QLabel(aParent) { }
void setPixmap(QPixmap aPicture);
void paintEvent(QPaintEvent *aEvent);
};
QPictureLabel.cpp (реализация)
#include "QPainter.h"
#include "QPictureLabel.hpp"
void QPictureLabel::paintEvent(QPaintEvent *aEvent)
{
QLabel::paintEvent(aEvent);
_displayImage();
}
void QPictureLabel::setPixmap(QPixmap aPicture)
{
_qpSource = _qpCurrent = aPicture;
repaint();
}
void QPictureLabel::_displayImage()
{
if (_qpSource.isNull()) //no image was set, don't draw anything
return;
float cw = width(), ch = height();
float pw = _qpCurrent.width(), ph = _qpCurrent.height();
if (pw > cw && ph > ch && pw/cw > ph/ch || //both width and high are bigger, ratio at high is bigger or
pw > cw && ph <= ch || //only the width is bigger or
pw < cw && ph < ch && cw/pw < ch/ph //both width and height is smaller, ratio at width is smaller
)
_qpCurrent = _qpSource.scaledToWidth(cw, Qt::TransformationMode::FastTransformation);
else if (pw > cw && ph > ch && pw/cw <= ph/ch || //both width and high are bigger, ratio at width is bigger or
ph > ch && pw <= cw || //only the height is bigger or
pw < cw && ph < ch && cw/pw > ch/ph //both width and height is smaller, ratio at height is smaller
)
_qpCurrent = _qpSource.scaledToHeight(ch, Qt::TransformationMode::FastTransformation);
int x = (cw - _qpCurrent.width())/2, y = (ch - _qpCurrent.height())/2;
QPainter paint(this);
paint.drawPixmap(x, y, _qpCurrent);
}
Использование: то же самое, что и обычная метка для отображения изображения с помощью setScaledContents
img_Result = new QPictureLabel(ui.parent);
layout = new QVBoxLayout(ui.parent);
layout->setContentsMargins(11, 11, 11, 11);
ui.parent->setLayout(layout);
layout->addWidget(img_Result);
//{...}
QPixmap qpImage(qsImagePath);
img_Result->setPixmap(qpImage);
Сохраните копию исходного pixmap
. Затем подключите сигнал resized
к слоту (или переопределите функцию resizeEvent()
), которая реализует это:
lblImage->setPixmap(pixmap.scaled(lblImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));