2011-04-13 31 views
25

Ya probé varios métodos para mostrar una imagen en un formulario, pero ninguno de ellos funciona como me gustaría.Mostrar la imagen en Qt para ajustar el tamaño de la etiqueta

He leído en muchos lugares que la forma más fácil es crear una etiqueta y usarla para mostrar la imagen. Tengo una etiqueta, cuyo tamaño es especificado por el diseño, pero si cargo una imagen con un mapa de píxeles, la etiqueta cambia de tamaño al tamaño de la imagen. Si utilizo la etiqueta img como propiedad text o css background, no se mostrará toda la imagen. Lo que me gustaría hacer es cargar la imagen y ajustarla en la etiqueta, sin cambiar el tamaño de la etiqueta, pero cuando cambie el tamaño de mi ventana, y al cambiar el tamaño de la etiqueta también, la imagen debe cambiar de tamaño para que siempre se ajuste en ello.

Si el único método es obtener el tamaño de la etiqueta y cambiar el tamaño del mapa de píxeles para que encaje, y manejar el evento de cambio de tamaño (señal), ¿cómo puedo cambiar el tamaño del mapa de píxeles? Espero no tener que guardar todo en una QImage y crear un mapa de píxel cada vez.

Además, ¿cómo puedo centrarlo? Si no puede adaptarse tanto al ancho como a la altura, me gustaría que la dimensión más pequeña se centre.

Ah, y no quiero usar controles deslizantes para manejar desbordamientos.

Respuesta

18

¿QLabel::setScaledContents(bool) ayuda? También puede haber información útil en el image viewer example también.

+2

Para una solución rápida que esto era un protector, pero me dio un resultado bastante fea por el estiramiento de la imagen (es decir: no manteniendo la relación de aspecto). Voy a marcar esto como una solución de todos modos. Gracias. – SinistraD

+0

Al usar PyQt5, esta solución no funciona. 'setScaledContents' no parece tener ningún efecto en el tamaño de la imagen mostrada. – ely

13

También responderé a mi propia pregunta, pero no la marcaré como solución, porque solicité una simple que se mencionó anteriormente. Terminé usando una solución no demasiado simple después de todo, por lo que cualquiera que también necesite hacer algo similar y tenga tiempo para jugar con ella, este es mi código de trabajo final. La idea es expandir QLabel y sobrecargar los métodos setPixmap y drawEvent.

QPictureLabel.hpp (archivo de cabecera)

#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 (aplicación)

#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); 
} 

Uso: lo mismo que usar una etiqueta normal en mostrar la imagen wirthout 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); 
+0

excelente respuesta, solo tengo problemas con mi widget padre, me da error – fredcrs

+0

me molesta cuando cambio el mapa de píxeles y cambie el tamaño de la pantalla – fredcrs

+0

Esto fue hace mucho tiempo (1 año es demasiado para mí), ni siquiera tengo Qt instalado más, pero podría ser capaz de ayudar. ¿Qué error está obteniendo y en qué línea? ¿Has probado la depuración? ¿O cómo "bichos"? Lo mejor que puedes hacer aquí, es publicar una pregunta de seguimiento aquí en stackoverflow, por lo tanto, tendrás una mayor posibilidad de obtener una respuesta de toda la base de usuarios. – SinistraD

16

En realidad, hay una resolución muy simple para este problema. Hay dos cosas que debe modificar:

  1. ajustar el contenido a escala en verdad (mencionado anteriormente)
  2. conjunto de directivas tamaño de la etiqueta a ignorado

    QLabel lblImage; 
    
    lblImage->setPixmap(QPixmap("big_image.jpg")); 
    
    lblImage->setScaledContents(true); 
    
    lblImage->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); 
    

Si el lblImage se cambio de tamaño automáticamente, la imagen se estirará al tamaño de la etiqueta.

+0

Supongo que no hay una solución simple para mantener la relación ancho/alto de la imagen? –

+0

El problema con "ignorado" es que la etiqueta no se puede usar para "expandir" el diseño. –

+0

Usando PyQt5, esto tampoco funciona. 'QSizePolicy.Ignored' no parece tener un efecto sobre si la imagen se redimensiona o no. – ely

6

Guarde una copia de su original pixmap alrededor.A continuación, conecte la señal resized a una ranura (o anular la función de resizeEvent()) que implementa esto:

lblImage->setPixmap(pixmap.scaled(lblImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); 
+0

upvoted duro! Muchas gracias –

Cuestiones relacionadas