Прокрутка QGraphicsView и масштабирование / обрезка изображений - PullRequest
5 голосов
/ 22 марта 2010

Я хотел бы иметь фоновое изображение в моем 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?

EDIT; Я также пытался использовать setBackgroundBrush, но получаю мозаичный фон даже при использовании масштабированного / обрезанного QImage / QPixmap.

EDIT; Мое решение до сих пор состояло в том, чтобы переопределить 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()));

}

Ответы [ 3 ]

1 голос
/ 22 марта 2010

Вы хотите sceneRect, а не просто width и height. Для масштабирования при изменении размера вы хотите подключить слот к sceneRectChanged, чтобы вы могли изменять размер изображения при изменении размера сцены.

Или вы можете получить QGraphicsView с переопределенным updateSceneRect, который изменяет размер изображения или, что еще лучше, просто переопределить drawBackground.

0 голосов
/ 05 ноября 2016

QGraphicsView::fitInView делает именно это.В соответствии с документацией он обычно указывается в resizeEvent.Использование sceneRects делает всю сцену вписывающейся в вид:

void CustomGraphicsView::resizeEvent(QResizeEvent *)
{
  this->fitInView(this->sceneRect());
}
0 голосов
/ 30 июля 2010

Я нашел ui->graphicsView->viewport()->size(), чтобы получить размер области просмотра. Работает только после отрисовки виджета.

...