c++ - QGraphicsView fitInView方法: resizing problems

标签 c++ qt qt5 qgraphicsview qgraphicsscene

我的 Qt 应用程序中有一个自定义 QGraphicsScene(我的类称为 MainScene)。该场景包含一定数量的矩形项目,这些项目就像放置在网格中一样

参见图1

此外,我可以动态更改此矩形网格的大小

图片No.2

此外,我希望这个网格适合大小,所以每次我按下“调整大小”按钮( picture №2 )时,场景都应该适合像 picture №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),它无法按我想要的方式工作

图片No.3

你能告诉我,为什么会发生这种情况吗?有什么办法可以解决吗?

更新: 这就是我创建网格的方式:

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 是我的自定义类,它派生自 QObjectQGraphicsItemroom 是 GraphicsCell 对象的 vector 。

最佳答案

当您添加项目时,如果它们超出了 sceneRect 范围,那么 sceneRect 就会增加,这就是您添加 30x30 时发生的情况> 但当您传递 20x20 时它不会减少,因此场景仍然很大,因此您观看 QScrollBar ,因此在这种情况下,解决方案是更新场景到 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()); // <---
} 

关于c++ - QGraphicsView fitInView方法: resizing problems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53795925/

相关文章:

c++ - 来自 qt4 设计生成的 h 文件的自定义插槽

c++ - std::list 严格弱排序

angular - Qt QWebEngine 远程调试 : Chrome developer tools no longer work

c++ - 运行 QFileDialog::getOpenFileName 而不需要单独的事件循环?

C++ 未解析的标识符 future

c++ - 这个表达式是一个 xvalue 吗?

c++ - Qt Crash SIGSEGV Fault while dynamically adding widgets to scrollArea (ui->scrollArea->setWidget(...))

c++ - 按键对实际 QMap 进行排序

c++ - 如何将带有自定义对象的容器从 C++ 传递到 QML?

c++ - 在 QML 中使用 C++-slot 返回命名空间中的类型