2016-10-21 3 views
1

Ich habe in den letzten Tagen mit diesem Problem zu kämpfen. Ich möchte in der Lage sein, zu wachsen und zu verkleinern, was auch immer die zugewiesene Pixmap in einem QLabel ist, wenn der Benutzer die Größe des Fensters ändert. Das Problem besteht darin, das Seitenverhältnis und die Bildqualität zu erhalten. Ein anderer Benutzer hier vorgeschlagen, dass ich die Farbe Ereignis für das Label neu zu implementieren - aber ich bin immer noch sehr verloren. Ich bin mir nicht einmal sicher, ob ich das paintEvent korrekt überschrieben habe. Ich würde hier für ein bisschen Beispielcode töten. DieseQt überschreiben QLabel PaintEvent

ist, wo ich bin an:

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

Haben Sie die [Lösung] (http://stackoverflow.com/a/8212120/1217285) aus der [verwandten Frage] (http://stackoverflow.com/questions/8211982/qt-resizing-a -qlabel-enthält-a-qpixmap-while-behalten-ihr-aspect-ratio)? Es sieht sehr ähnlich aus, was Sie erreichen wollen. – Dmitry

Antwort

1

Hier ist eine mögliche Implementierung einer QLabel Unterklasse ist, dass seine pixmap Inhalt skaliert, während das Seitenverhältnis zu halten. Es ist basierend auf dem Weg implementiert QLabel::paintEventis implemented.

Wenn Sie es in einem Layout verwenden, können Sie auch seine Größenrichtlinie auf QSizePolicy::Expanding setzen, so dass zusätzlicher Platz im Layout von QLabel für eine größere Anzeige des Pixmap-Inhalts belegt wird.

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

Ich denke, das ist besser als die Lösung in this answer, wie die QLabel hier kümmert sich seine pixmap der Größe ändern. Es ist also nicht erforderlich, die Größe jedes Mal, wenn das Eltern-Widget in der Größe geändert wird, und jedes Mal, wenn ein neues Pixmap darauf gesetzt wird, manuell zu ändern.

+0

Vielen Dank für Ihre Hilfe, dies hat alles geklärt. –