QGraphicsView не уважает heightForWidth () для поддержания соотношения сторон? - PullRequest
0 голосов
/ 25 марта 2020

Я создал небольшой пример MVCE для воспроизведения проблемы с соотношением сторон изображения с QGraphicsView.

Опираясь на это я понял, что при масштабировании изображения корректно вычисляется соотношение сторон, но каждый раз, когда я изменяю размер QGraphicsView, оно игнорирует мое значение heightForWidth() (которое фактически возвращает правильное height) ,

ImageView.h

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QResizeEvent>
#include <QWidget>
#include <QImage>
#include <QPixmap>

class ImageView : public QGraphicsView
{
    Q_OBJECT

public:
    ImageView(QWidget* parent = nullptr);

    void setImage(const QImage& image);

    virtual int heightForWidth(int width) const override;

protected:

    virtual void resizeEvent(QResizeEvent *event) override;

private:
    QGraphicsScene* m_scene;

    QImage m_image;
    QPixmap m_pixImage;

    int m_rows;
    int m_cols;
};

ImageView. cpp

#include "imageview.h"
#include <QDebug>

ImageView::ImageView(QWidget *parent) :
    QGraphicsView{parent},
    m_scene{new QGraphicsScene{this}},
    m_rows{0},
    m_cols{0}
{
    setScene(m_scene);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    QSizePolicy p(QSizePolicy::Minimum,QSizePolicy::Minimum);
    p.setHeightForWidth(true);
    setSizePolicy(p);

    setFrameStyle(0);

    setMouseTracking(true);
}

void ImageView::setImage(const QImage &image)
{
    m_image = image;

    m_cols = image.width();
    m_rows = image.height();

    m_pixImage = QPixmap::fromImage(image);

    m_scene->addPixmap(m_pixImage);
    fitInView(m_scene->itemsBoundingRect(),Qt::KeepAspectRatio);
}

/* virtual */ int ImageView::heightForWidth(int width) const
{
    int height = (m_cols != 0) ? width * m_rows / m_cols : width;
    qDebug() << "Height for width: " << height;

    return height;
}

void ImageView::resizeEvent(QResizeEvent *event)
{
    m_scene->clear();

    qDebug() << "Graphics View: " << event->size();
    QPixmap pxImg = m_pixImage.scaled(event->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);

    if(!pxImg.isNull())
    {
      qDebug() << "Image: " << pxImg.size();
      qDebug() << "Graphics View: " << event->size();
      m_scene->addPixmap(pxImg);
    }

    fitInView(m_scene->itemsBoundingRect(),Qt::KeepAspectRatio);
    QGraphicsView::resizeEvent(event);
}

MainWindow.h

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

MainWindow. cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->graphicsView->setImage(QImage("656780.png"));
}

MainWindow::~MainWindow()
{
    delete ui;
}

Выход:

Height for width:  586 // ideal height for the width to maintain aspect ratio (width should be 781)
Graphics View:  QSize(782, 544) // instead height is set to 544 (width should be 725)
Image:  QSize(725, 544) // scaling the image to the resize event size with aspect ratio 
                        // turns out 725 is right for a width of 544
Graphics View:  QSize(782, 544) // same here

As В результате вывода мое изображение никогда не масштабируется до точного размера QGraphicsView при изменении размера.

Как мне решить эту проблему? Мой расчет неверен? Или я что-то упустил?

1 Ответ

0 голосов
/ 27 марта 2020

Хорошо, после долгих попыток я понял, что мне не нужно масштабировать изображение вручную в QGraphicsView. fitInView() фактически делает это автоматически. Чтобы ответить на мой вопрос, KeepAspectRatioByExpanding является ответом.

void ImageView::resizeEvent(QResizeEvent *event)
{
    fitInView(m_scene->itemsBoundingRect(),Qt::KeepAspectRatioByExpanding);
    QGraphicsView::resizeEvent(event);
}

Это масштабирует изображение вместе с размером QGraphicsView. Следует иметь в виду, что полосы прокрутки могут отображаться, если изображение масштабируется или сжимается ниже исходного размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...