2016-10-21 3 views
1

저는 지난 이틀간이 문제로 고생하고 있습니다. 사용자가 창 크기를 조정할 때 할당 된 Pixmap이 QLabel에있는 것이 무엇이든간에 그 크기를 늘리고 줄일 수 있기를 원합니다. 문제는 종횡비와 이미지 품질을 유지하는 것입니다. 여기에있는 또 다른 사용자는 레이블에 대한 페인트 이벤트를 다시 구현할 것을 제안했지만 여전히 잃어 버렸습니다. 나는 paintEvent를 올바르게 오버 라이딩했는지 확신 할 수 없다. 나는 여기서 약간의 샘플 코드를 위해 죽일 것이다.Qt QLabel PaintEvent 무시하기

void MyLabel::paintEvent(QPaintEvent * event) 
{ 
    //if this widget is assigned a pixmap 
    //paint that pixmap at the size of the parent, aspect ratio preserved 
    //otherwise, nothing 
} 
+0

[관련 질문] (http://stackoverflow.com/questions/8211982/qt-resizing-a)에서 [솔루션] (http://stackoverflow.com/a/8212120/1217285)을 보았습니까? -a-qpixmap-as-its-its-aspect-ratio)? 당신이 성취하고자하는 것에 매우 가깝게 보인다. – Dmitry

답변

1

여기의 가로 세로 비율을 유지하면서 그 픽스맵의 컨텐츠를 확장 가능한 QLabel 서브 클래스의 가능한 구현입니다 : 내가 어디에 있어요

이입니다. 이는 QLabel::paintEventis implemented에 기반하여 구현됩니다.

레이아웃에서 사용하는 경우 크기 정책을 QSizePolicy::Expanding으로 설정하여 레이아웃의 추가 공간을 QLabel이 차지하도록하여 픽스맵 콘텐츠를 더 크게 표시 할 수 있습니다.

#include <QApplication> 
#include <QtWidgets> 

class PixmapLabel : public QLabel{ 
public: 
    explicit PixmapLabel(QWidget* parent=nullptr):QLabel(parent){ 
     //By default, this class scales the pixmap according to the label's size 
     setScaledContents(true); 
    } 
    ~PixmapLabel(){} 

protected: 
    void paintEvent(QPaintEvent* event); 
private: 
    //QImage to cache the pixmap() 
    //to avoid constructing a new QImage on every scale operation 
    QImage cachedImage; 
    //used to cache the last scaled pixmap 
    //to avoid calling scale again when the size is still at the same 
    QPixmap scaledPixmap; 
    //key for the currently cached QImage and QPixmap 
    //used to make sure the label was not set to another QPixmap 
    qint64 cacheKey{0}; 
}; 

//based on the implementation of QLabel::paintEvent 
void PixmapLabel::paintEvent(QPaintEvent *event){ 
    //if this is assigned to a pixmap 
    if(pixmap() && !pixmap()->isNull()){ 
     QStyle* style= PixmapLabel::style(); 
     QPainter painter(this); 
     drawFrame(&painter); 
     QRect cr = contentsRect(); 
     cr.adjust(margin(), margin(), -margin(), -margin()); 
     int align= QStyle::visualAlignment(layoutDirection(), alignment()); 
     QPixmap pix; 
     if(hasScaledContents()){ //if scaling is enabled 
      QSize scaledSize= cr.size() * devicePixelRatioF(); 
      //if scaledPixmap is invalid 
      if(scaledPixmap.isNull() || scaledPixmap.size()!=scaledSize 
        || pixmap()->cacheKey()!=cacheKey){ 
       //if cachedImage is also invalid 
       if(pixmap()->cacheKey() != cacheKey){ 
        //reconstruct cachedImage 
        cachedImage= pixmap()->toImage(); 
       } 
       QImage scaledImage= cachedImage.scaled(
          scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); 
       scaledPixmap= QPixmap::fromImage(scaledImage); 
       scaledPixmap.setDevicePixelRatio(devicePixelRatioF()); 
      } 
      pix= scaledPixmap; 
     } else { // no scaling, Just use pixmap() 
      pix= *pixmap(); 
     } 
     QStyleOption opt; 
     opt.initFrom(this); 
     if(!isEnabled()) 
      pix= style->generatedIconPixmap(QIcon::Disabled, pix, &opt); 
     style->drawItemPixmap(&painter, cr, align, pix); 
    } else { //otherwise (if the label is not assigned to a pixmap) 
     //call base paintEvent 
     QLabel::paintEvent(event); 
    } 
} 

//DEMO program 
QPixmap generatePixmap(QSize size) { 
    QPixmap pixmap(size); 
    pixmap.fill(Qt::white); 
    QPainter p(&pixmap); 
    p.setRenderHint(QPainter::Antialiasing); 
    p.setPen(QPen(Qt::black, 10)); 
    p.drawEllipse(pixmap.rect()); 
    p.setPen(QPen(Qt::red, 2)); 
    p.drawLine(pixmap.rect().topLeft(), pixmap.rect().bottomRight()); 
    p.drawLine(pixmap.rect().topRight(), pixmap.rect().bottomLeft()); 
    return pixmap; 
} 


int main(int argc, char *argv[]) 

{ 
    QApplication a(argc, argv); 


    QPixmap pixmap= generatePixmap(QSize(1280, 960)); 
    PixmapLabel label; 
    label.setPixmap(pixmap); 
    label.setAlignment(Qt::AlignCenter); 
    label.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 
    label.setMinimumSize(320, 240); 
    label.show(); 

    return a.exec(); 
} 

은 내가 QLabel 여기에 그 픽스맵의 크기를 조정을 담당로서이, this answer의 솔루션보다 더 나은 생각합니다. 따라서 상위 위젯 크기를 조정할 때마다 매번 새로운 픽스맵을 설정할 때마다 수동으로 크기를 조정할 필요가 없습니다.

+0

도움을 주셔서 감사합니다. –

관련 문제