QGraphicsView метод fitInView: изменение размера проблем - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть собственный QGraphicsScene (мой класс называется MainScene) в моем приложении Qt.Эта сцена содержит некоторое количество предметов Rect, которые расположены как бы в сетке

см. Рисунок №1

Также я могу изменить размер этогосетка Rects динамически

картинка №2

Более того, я хочу, чтобы эта сетка соответствовала размеру, поэтому каждый раз, когда я нажимаю на кнопку Resize ( картинка №2 ), сцена должна соответствовать размеру, как на картинка №1 .Я реализую его, используя следующий код:

void MainWindow::on_resizeButton_clicked()
{
    int h = ui->heightSpinBox->value(); //height of the grid
    int w = ui->widthSpinBox->value(); //width of the grid
    scene->resize(h, w); //adding required amount of rects

    ui->graphicsView->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
    ui->graphicsView->centerOn(0, 0);
}

Проблема заключается в следующем: когда я выбираю высоту и ширину, где новая высота больше текущей высоты, а новая ширина больше текущей ширины (например, текущая сетка 20x20 иЯ изменяю его размер до 30x30) он работает правильно, но когда я выбираю высоту и ширину, которые меньше текущего размера (например, текущая сетка 30x30, и я изменяю его размер до 20x20), он не работает так, как я хочу

картинка №3

Можете ли вы сказать мне, почему это происходит?Есть ли способы исправить это?

UPD: вот как я создаю сетку:

void MainScene::resize(int rows, int cols)
{
    clearScene(rows, cols);
    populateScene(rows, cols);
}

void MainScene::clearScene(int rows, int cols)
{
    if(rows < roomHeight)
    {
        for(int i = rows; i < roomHeight; ++i)
        {
            for(int j = 0; j < roomWidth; ++j)
            {
                removeItem(room[i][j]);
                delete room[i][j];
            }
        }
        room.resize(rows);
        roomHeight = rows;
    }

    if(cols < roomWidth)
    {
        for(int i = 0; i < roomHeight; ++i)
        {
            for(int j = cols; j < roomWidth; ++j)
            {
                removeItem(room[i][j]);
                delete room[i][j];
            }
            room[i].resize(cols);
        }
        roomWidth = cols;
    }
}

void MainScene::populateScene(int rows, int cols)
{
    if(rows > roomHeight)
    {
        room.resize(rows);
        for(int i = roomHeight; i < rows; ++i)
        {
            room[i].resize(roomWidth);
            for(int j = 0; j < roomWidth; ++j)
            {
                    room[i][j] = new GraphicsCell();
                    room[i][j]->setPos(j * 30, i * 30);
                    addItem(room[i][j]);
            }
        }
        roomHeight = rows;
    }

    if(cols > roomWidth)
    {
        for(int i = 0; i < roomHeight; ++i)
        {
            room[i].resize(cols);
            for(int j = roomWidth; j < cols; ++j)
            {
                room[i][j] = new GraphicsCell();
                room[i][j]->setPos(j * 30, i * 30);
                addItem(room[i][j]);
            }
        }
        roomWidth = cols;
    }
}

GraphicsCell - мой пользовательский класс, производный от QObject и QGraphicsItem,room - это вектор объектов GraphicsCell.

1 Ответ

0 голосов
/ 15 декабря 2018

Когда вы добавляете элементы, и если они выходят за пределы sceneRect, тогда sceneRect увеличивается, и это то, что происходит, когда вы добавляете 30x30, но оно не уменьшается, когда вы передаете 20x20, поэтомусцена все еще большая, поэтому вы смотрите QScrollBar s, поэтому в этом случае решение состоит в том, чтобы обновить размер сцены до itemsBoundingRect().

void MainWindow::on_resizeButton_clicked()
{
    int h = ui->heightSpinBox->value(); //height of the grid
    int w = ui->widthSpinBox->value(); //width of the grid
    scene->resize(h, w); //adding required amount of rects

    ui->graphicsView->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
    scene->setSceneRect(scene->itemsBoundingRect()); // <---
} 
...