2016-10-21 25 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)を見ましたか?アスペクト比を維持しながら、-qlapel-a-qpixmapを含む)?あなたが達成しようとしているものに非常に近いように見えます。 – 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

ご協力いただきありがとうございます。これですべてがクリアされました。 –

関連する問題