2
votes

I have a custom QGraphicsScene (my class is called MainScene) in my Qt Application. This scene contains some quantity of Rect items, that are placed as if in a grid

see picture №1

Also, I can change size of this grid of Rects dynamically

picture №2

Moreover, I want this grid to be fitted to size, so every time I press on Resize button (picture №2), scene should be fitted to size like in the picture №1. I implement it using following code:

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);
}

The problem is: when I choose heigth and width, where new height is bigger than current heigth and new width is bigger than current width (e.g. current grid is 20x20 and I resize it to 30x30) it works properly, but when I choose height and width that are smaller than current size (e.g. current grid is 30x30 and I resize it to 20x20) it doesn't work as I want

picture №3

Can you tell me, why is this happening? Are there any ways to fix it?

UPD: This is how I create a grid:

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 is my custom class, that is derived from QObject and QGraphicsItem. room is a vector of GraphicsCell objects.

1
shows how you created the gridseyllanesc
@eyllanesc See UPDАндрей Диденко
MainScene is the QGraphicsScene?eyllanesc
@eyllanesc yes. Sorry, I didn't match it in question. I will correct itАндрей Диденко

1 Answers

2
votes

When you add items and if they are out of the sceneRect then the sceneRect is increased, and that's what happens when you add the 30x30 but it does not decrease when you pass the 20x20 so the scene is still big so you watch the QScrollBars, so in this case the solution is to update the size of the scene to the 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()); // <---
}