Прокрутка QGraphicsView и масштабирование / обрезка изображения
-
21-09-2019 - |
Вопрос
Я хотел бы иметь фоновое изображение в моем QGraphicsView, которое всегда масштабируется (и при необходимости обрезается) до размера окна просмотра, без полос прокрутки и без прокрутки с помощью клавиатуры и мыши.Приведенный ниже пример - это то, что я делаю для масштабирования и обрезки изображения в окне просмотра, но для обрезки я использую случайные значения, которые извлекаются из эфира.Я хотел бы логичное решение?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this);
ui->graphicsView->resize(800, 427);
// MainWindow is 800x480, GraphicsView is 800x427. I want an image that
// is the size of the graphicsView.
ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// the graphicsView still scrolls if the image is too large, but
// displays no scrollbars. I would like it not to scroll (I want to
// add a scrolling widget into the QGraphicsScene later, on top of
// the background image.)
QPixmap *backgroundPixmap = new QPixmap(":/Valentino_Bar_Prague.jpg");
QPixmap sized = backgroundPixmap->scaled(
QSize(ui->graphicsView->width(),
ui->graphicsView->height()),
Qt::KeepAspectRatioByExpanding); // This scales the image too tall
QImage sizedImage = QImage(sized.toImage());
QImage sizedCroppedImage = QImage(sizedImage.copy(0,0,
(ui->graphicsView->width() - 1.5),
(ui->graphicsView->height() + 19)));
// so I try to crop using copy(), and I have to use these values
// and I am unsure why.
QGraphicsPixmapItem *sizedBackground = scene->addPixmap(
QPixmap::fromImage(sizedCroppedImage));
sizedBackground->setZValue(1);
ui->graphicsView->setScene(this->scene);
}
Я хотел бы знать способ масштабирования и обрезки изображения до размера QGraphicsView, который будет работать даже при изменении размера QGraphicsView.Откуда берутся цифры 1.5 и 19?
Редактировать;Я также пытался использовать setBackgroundBrush, но я получаю плиточный фон, даже при использовании масштабированного / обрезанного QImage / QPixmap.
Редактировать;До сих пор моим решением было переопределить drawBackground(), чтобы получить желаемый результат, но это по-прежнему не помогает мне научиться изменять размер изображения в соответствии с размером окна просмотра qgraphicsview.Будем весьма признательны за любые дальнейшие ответы.
void CustomGraphicsView::drawBackground( QPainter * painter, const QRectF & rect )
{
qDebug() << "background rect: " << rect << endl;
QPixmap *backgroundPixmap = new QPixmap(":/Valentino_Bar_Prague.jpg");
QPixmap sized = backgroundPixmap->scaled(QSize(rect.width(), rect.height()), Qt::KeepAspectRatioByExpanding);
painter->drawPixmap(rect, sized, QRect(0.0, 0.0, sized.width(), sized.height()));
}
Решение
Ты хочешь sceneRect
не просто width
и height
.Для масштабирования при изменении размера, к которому вы хотите подключить слот sceneRectChanged
таким образом, вы можете изменять размер изображения всякий раз, когда сцена меняет размер.
Или вы можете вывести QGraphicsView
с переопределенным updateSceneRect
это изменяет размер изображения, а еще лучше, просто переопределяет drawBackground
.
Другие советы
Я нашел ui->graphicsView->viewport()->size()
чтобы получить размер видового экрана.Однако работает только после того, как виджет был нарисован.
В QGraphicsView::fitInView
делает именно это.Согласно документации, он обычно помещается в resizeEvent
.Используя sceneRects
позволяет всей сцене вписаться в общий вид:
void CustomGraphicsView::resizeEvent(QResizeEvent *)
{
this->fitInView(this->sceneRect());
}