Подтвердить что ты не робот

Qt5 С++ QGraphicsView: изображения не подходят для рамки просмотра

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

Итак, вот мой код:

image = new QImage(data.absoluteFilePath()); // variable data is defined when calling this method
scn = new QGraphicsScene(this); // object defined in header
ui->graphicsView->setScene(scn);
scn->addPixmap(QPixmap::fromImage(*image));
ui->graphicsView->fitInView(scn->itemsBoundingRect(),Qt::KeepAspectRatio);

Я пытался найти множество решений, которые я нашел в Интернете, но никто мне не помог. Изображение имеет размер около 40 x 60 пикселей, когда кадр составляет 200 x 400 пикселей. Что может быть неправильным?

Вот пример того, что производится с кодом выше и что я хочу выйти: enter image description here

4b9b3361

Ответ 1

Решение для моего вопроса - showEvent() для Dialog. Это означает, что вы не можете вызвать fitInView() перед тем, как будет показана форма, поэтому вам нужно создать диалог showEvent(), и изображение будет установлено в кадр QGraphics View.

И пример кода, который вы должны добавить в код диалога:

void YourClass::showEvent(QShowEvent *) {
    ui->graphicsView->fitInView(scn->sceneRect(),Qt::KeepAspectRatio);
}

Ответ 2

Причина, по которой вы не видите свое изображение так, как хотите, потому что функция QGraphicsView fitInView не делает то, что вы думаете.

Он гарантирует, что объект находится внутри области просмотра, без какого-либо перекрытия границ представления, поэтому, если ваш объект не был в представлении, вызов метода fitInView заставит представление перемещаться/масштабироваться и т.д., чтобы гарантировать, что объект полностью виден. Кроме того, если окно просмотра слишком мало для области, предоставленной для fitInView, ничего не произойдет.

Итак, чтобы получить то, что вы хотите, сопоставьте экстенты координат GraphicsView с GraphicsScene, а затем установите координаты сцены изображения для них. Как сказал @VBB, если вы растянете изображение, оно может изменить аспект raio, поэтому вы можете использовать scaledToWidth для QPixmap.

Что-то вроде этого: -

QRectF sceneRect = ui->graphicsView->sceneRect(); // the view scene coords
QPixmap image = QPixmap::fromImage(*image);

// scale the image to the view and maintain aspect ratio
image = image.scaledToWidth(sceneRect.width());

QGraphicsPixmapItem* pPixmap = scn->addPixmap(QPixmap::fromImage(*image));

// overloaded function takes the object and we've already handled the aspect ratio
ui->graphicsView->fitInView(pPixmap);

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

Ответ 3

Вам нужно обработать событие изменить размер, я предполагаю, что он предназначен для воспроизведения:

bool YourDialog::eventFilter(QObject *obj, QEvent *event)
{
        if (event->type() == QEvent::Show){
            ui->conceptView->fitInView(conceptScene->sceneRect(), Qt::KeepAspectRatio);
        }

        if (event->type() == QEvent::Resize){
            ui->conceptView->fitInView(conceptScene->sceneRect(), Qt::KeepAspectRatio);
        }
}

Ответ 4

Я думаю, что вы должны масштабировать изображение. Я делаю это, и это работает хорошо:

QRect ref_Rect = QRect(x_pos, y_pos, Width, Length);
QGraphicsView* qGraph = new QGraphicsView(this);
qGraph->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
qGraph->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
qGraph->setGeometry(ref_Rect);

QGraphicsScene* scene = new QGraphicsScene(qGraph);
scene->setSceneRect(0, 0, ref_Rect.width(), ref_Rect.height());
qGraph->setScene(scene);

QImage *image = new QImage();
image->load("folder/name.png");
*image = image->scaled(ref_Rect.width(), ref_Rect.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(*image));    

scene->addItem(item);
qGraph->show();