Soru Etiket boyutuna sığdırmak için görüntüyü Qt olarak görüntüleyin


Bir form üzerinde bir görüntüyü görüntülemek için birkaç yöntem denedim, ancak bunların hiçbiri istediğim gibi çalışmıyor.

En kolay yolun bir etiket oluşturup resmi görüntülemek için kullanabileceği birçok yer okudum. Düzeni tarafından belirtilen boyutta bir etiketim var, ancak bir görüntüyü pixmap ile yüklediğimde, etiket görüntünün boyutuna yeniden boyutlandırılır. İmg etiketini text veya css background özelliği olarak kullanırsam, resmin tamamını göstermez. Yapmak istediğim, etiketi yüklemek, etiketin boyutunu değiştirmemek, ancak etiketimi yeniden boyutlandırmak değil, penceremi yeniden boyutlandırdığımda ve bu da etiketi yeniden boyutlandırmak, görüntü her zaman sığacak şekilde yeniden boyutlandırılmaktır. bunun içine.

Tek yöntem, etiketin boyutunu almak ve pixmap'i yeniden boyutlandırmak ve yeniden boyutlandırma olayını (sinyalini) işlemek için piksel şeklini yeniden boyutlandırmaksa piksumu nasıl yeniden boyutlandırabilirim? Umarım her şeyi bir QImage'a kaydetmem ve her seferinde bir piksoma oluşturmam gerekmeyecek.

Ayrıca, onu nasıl merkezleyebilirim? Hem genişliğe hem de yüksekliğe sığamıyorsa, daha küçük boyutun ortalanmasını istiyorum.

Oh, ve taşmaları işlemek için kaydırıcı kullanmak istemiyorum.


25
2018-04-13 17:24


Menşei




Cevaplar:


does QLabel :: setScaledContents (bool) yardım et? Ayrıca bazı yararlı bilgiler de olabilir. resim görüntüleyici örneği çok.


18
2018-04-13 17:55



Hızlı bir çözüm için bu bir koruyucu oldu, ancak görüntüyü gererek bana oldukça çirkin bir sonuç verdi (yani: en boy oranını koruyarak). Bunu bir çözüm olarak işaretleyeceğim. Teşekkürler. - Máthé Endre-Botond
PyQt5'i kullanarak bu çözüm işe yaramıyor. setScaledContents Görüntülenen görüntü boyutu üzerinde herhangi bir etkisi yoktur. - ely


Aslında bu problem için çok basit bir çözüm var. Değiştirmeniz gereken iki şey var:

  1. Ölçeklendirilmiş içeriği true olarak ayarlayın (yukarıda belirtilen)
  2. Etiketin boyut politikasını yoksayılacak şekilde ayarla

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

LblImage otomatik olarak yeniden boyutlandırılıyorsa, görüntü etiketin boyutuna göre strech olacaktır.


17
2017-08-08 16:18



Sanırım görüntü genişliği / yükseklik oranını korumak için basit bir çözüm yok mu? - Eric Lemanissier
"Yok sayılan" ile ilgili sorun, etiketin yerleşimi "genişletmek" için kullanılamamasıdır. - Lennart Rolland
PyQt5'i kullanarak, bu da işe yaramaz. QSizePolicy.Ignored Resmin yeniden boyutlandırılıp artırılmayacağı üzerinde bir etkisi yoktur. - ely


Ben de kendi sorumu cevaplayacağım, ama çözüm olarak işaretlemeyeceğim, çünkü yukarıda verilen basit bir talepte bulundum. Her şeyden önce çok basit bir çözüm kullanmaya son verdim, dolayısıyla benzer bir şey yapması gereken ve onunla oynamak için zamanı olan herkes işte benim son çalışma kodum. Fikir QLabel'i genişletmek ve setPixmap ve drawEvent yöntemlerini aşırı yüklemektir.

QPictureLabel.hpp (başlık dosyası)

#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 (Uygulama)

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

kullanım : setScaledContents görüntüsünü görüntülemek için normal bir etiket kullanmakla aynı

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
2018-04-23 11:13



büyük yanıt, sadece benim ana pencere aracı ile sorun yaşıyorum, bugs - fredcrs
pixmap'i değiştirip ekranı yeniden boyutlandırdığımda hata - fredcrs
Bu oldukça uzun bir süre önce (1 yıl benim için çok fazla), artık Qt yüklü değil, ama yardımcı olabilirim. Hangi hatayı alıyorsunuz ve hangi sırayla? Hata ayıklamayı denediniz mi? Ya da nasıl "hata"? Burada yapabileceğiniz en iyi şey, stackoverflow üzerinde bir takip sorusu göndermek, böylece tüm kullanıcı tabanından bir cevap için daha büyük bir şans elde edersiniz. - Máthé Endre-Botond
Özür dilerim, ana pencerem yeniden boyutlandırıldığında yeniden etiketlenmiş bir etiketim vardı, bu yüzden etiketin arka planı sorun yaratıyordu, etiketin içindeki görüntü değil - kodunuz - etiketli bir arka plan oluşturmam sabitlendi - label-> setAutoFillBackground (true); - fredcrs
Bu QLabel uzantısı için çok teşekkür ederim! Çalışma saatlerini kurtardım. - Greg Kramida


Orijinalinizin bir kopyasını saklayın pixmap etrafında. Sonra bağla resized bir yuvaya sinyal vermek (veya resizeEvent() Bunu uygulayan işlev):

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

6
2018-04-23 16:36



çok sert! çok teşekkür ederim - fr_andres