Afficher l'image dans Qt pour s'adapter à la taille de l'étiquette
j'ai déjà essayé plusieurs méthodes pour afficher une image sur un formulaire, mais aucune ne fonctionne comme je le voudrais.
j'ai lu à plusieurs endroits que le plus simple est de créer une étiquette et l'utiliser pour afficher l'image. J'ai une étiquette, dont la taille est spécifiée par la mise en page, mais si je charge une image dans un pixmap, l'étiquette est redimensionnée à la taille de l'image. Si j'utilise la balise img comme propriété de texte ou de fond css, elle n'affichera pas l'image entière. Ce que je voudrais faire est de charger l'image et la place dans l'étiquette, ne pas changer l'étiquette de taille, mais quand j'ai redimensionner ma fenêtre, et que le redimensionnement de l'étiquette ainsi, l'image doit être redimensionnée trop de sorte qu'il sera toujours à adapter.
si la seule méthode est d'obtenir la taille de l'étiquette, et redimensionner le pixmap pour qu'il corresponde, et gérer l'événement redimensionner (signal), Comment puis-je redimensionner le pixmap? J'espère que je n'aurai pas besoin de tout enregistrer dans un QImage et d'en créer un pixmap à chaque fois.
Aussi, comment je peux le centrer? S'il ne peut pas tenir à la fois la largeur et la hauteur, je voudrais que la plus petite dimension soit centrée.
Oh, et je ne veux pas utiliser les curseurs pour gérer les débordements.
4 réponses
QLabel:: setScaledContents (bool) de l'aide? Il peut aussi y avoir des informations utiles dans le exemple de visualiseur d'image trop.
en fait il y a une résolution très simple pour ce problème. Il y a deux choses que vous devriez modifier:
- définissez le contenu scalé à true (mentionné ci-dessus)
définir la Politique de taille du label à ignorer
QLabel lblImage; lblImage->setPixmap( QPixmap( "big_image.jpg" ) ); lblImage->setScaledContents( true ); lblImage->setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
si le lblImage est redimensionné automatiquement, l'image sera striée à la taille de l'étiquette.
je vais aussi répondre à ma propre question, mais je ne la marquerai pas comme solution, parce que j'ai demandé une simple qui a été donnée ci-dessus. J'ai fini par utiliser une solution pas trop simple après tout, donc quiconque a également besoin de faire quelque chose de similaire et a le temps de jouer avec elle voici mon code de travail final. L'idée est d'étendre le QLabel et de surcharger les méthodes setPixmap et drawEvent.
QPictureLabel.hpp (en-tête fichier)
#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.rpc (mise en œuvre)
#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);
}
Utilisation: la même chose qu'utiliser une étiquette normale pour afficher l'image sans les contenus setscaled
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);
conservez une copie de votre original pixmap
autour de. Alors connectez le resized
signal vers une fente (ou Outrepasser le resizeEvent()
function) qui implémente ceci :
lblImage->setPixmap(pixmap.scaled(lblImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));