QGraphicsScene::clear不会改变sceneRect。

5

我有一个 QGraphicsScene “scene” 和 QGraphicsView “graphicsView”。

我有一个绘图方法。当需要重绘所有图形时,我调用此方法。一切正常。但是我意识到 scene->clear() 不会更改 sceneRect。

我也尝试过:

graphicsView->items().clear();
scene->clear();
graphicsView->viewport()->update();

接着,如果我通过以下方式获取sceneRect:

QRectF bound = scene->sceneRect();
qDebug() << bound.width();
qDebug() << bound.height();

我希望bound.width和bound.height的值为'0'。但它们并不是。我每次都看到之前的值。当我清除场景本身时,如何清除sceneRect?

使用graphicsView->fitInView()方法时,sceneRect保持不变会导致一些问题。我使用以下代码:

QRectF bounds = scene->sceneRect();
bounds.setWidth(bounds.width()*1.007);          // to give some margins
bounds.setHeight(bounds.height());              // same as above
graphicsView->fitInView(bounds);

尽管我完全清除了场景并只添加了一个相当小的矩形,但由于sceneRect仍然太大,该矩形无法适合视图。
我希望我能解释清楚我的问题。
2个回答

3
Qt文档(我要强调一下)中可以了解到:
场景矩形是一个属性,用于定义场景的边界矩形。主要由QGraphicsView用于确定视图的默认可滚动区域,以及由QGraphicsScene用于管理项索引。
如果未设置或设置为null QRectF,则sceneRect()将返回自创建场景以来所有项的最大边界矩形(即,当项添加到场景中或移动到场景中时增长但不会缩小的矩形)。
因此,唯一缩小sceneRect的方法是使用setSceneRect。

1
更好的问题是为什么需要设置场景矩形?如果你有一个较小的场景,不需要设置它。相反,将项目添加到场景中,并根据项目边界矩形适应视图,如下面的示例所示:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsRectItem>
#include <QPointF>
#include <QDebug>
#include <qglobal.h>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    _scene = new QGraphicsScene(this);
    ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui->graphicsView->setScene(_scene);

    connect(ui->button, SIGNAL(released()), this, SLOT(_handleRelease()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

int MainWindow::_random(int min, int max)
{
    return qrand() % ((max + 1) - min) + min;
}

void MainWindow::_handleRelease()
{

    _scene->clear();

    QGraphicsRectItem* pRect1 = _scene->addRect(0, 0, _random(50,100), _random(50,100));
    QGraphicsRectItem* pRect2 = _scene->addRect(0, 0, _random(20,50), _random(20,50));

    pRect1->setPos(QPoint(40,40));
    pRect2->setPos(QPoint(20,20));

    ui->graphicsView->fitInView(_scene->itemsBoundingRect(),Qt::KeepAspectRatio);
}

如果你有一个拥有数百个项目的大场景,这种方法会很慢,因为:

如果未设置场景矩形,QGraphicsScene将使用所有项的边界区域(由itemsBoundingRect()返回)作为场景矩形。然而,itemsBoundingRect()是一个相对耗时的函数,因为它通过收集场景上每个项的位置信息来运行。因此,在处理大型场景时,应始终设置场景矩形。


使用 graphicsView->fitInView(scene->itemsBoundingRect()) 代替 graphicsView->fitInView(scene->sceneRect()) 解决了我的问题。但是,sceneRect 仍然太大。删除项目不会改变 sceneRect。我认为这个问题将来会给我带来一些问题 :) - mehmetfa
在创建场景后不需要设置场景矩形。如果没有设置,则将始终基于其内部项的边界矩形进行计算。您是否尝试删除设置场景矩形的那一行? - Alexander Tyapkov
@mehmetfa 如果您的问题已解决,请将问题标记为已解决。 - Alexander Tyapkov
实际上,我并没有设置sceneRect。正如你所说,它是根据内部的items计算出来的。但是它总是随着添加而增长,而不是随着删除项目而减小。只有通过删除items来减小scene->itemsBoundingRect。 - mehmetfa
@mehmetfa 这很奇怪。在我的示例场景中,矩形保持不变,大小没有增加。 - Alexander Tyapkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接