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.

25
demandé sur Tetsujin no Oni 2011-04-13 21:24:43

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.

18
répondu Arnold Spence 2015-10-05 10:05:19

en fait il y a une résolution très simple pour ce problème. Il y a deux choses que vous devriez modifier:

  1. définissez le contenu scalé à true (mentionné ci-dessus)
  2. 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.

17
répondu bukkfa 2016-05-19 09:07:05

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);
13
répondu Máthé Endre-Botond 2011-04-23 11:13:52

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));
6
répondu Tim MB 2016-04-23 16:36:42