QGraphicsScene::clear 不改变 sceneRect

QGraphicsScene::clear doesn't change sceneRect

我有一个 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 保持不变会带来一些问题 method.I 使用以下代码:

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 仍然太大,该矩形不适合视图。

我希望我能解释我的问题。

更好的问题是为什么需要设置场景矩形?如果你有一个较小的场景,请不要设置它。而是将项目添加到场景并根据项目边界矩形适合视图,如下面的示例所示:

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

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

If the scene rect is unset, QGraphicsScene will use the bounding area of all items, as returned by itemsBoundingRect(), as the scene rect. However, itemsBoundingRect() is a relatively time consuming function, as it operates by collecting positional information for every item on the scene. Because of this, you should always set the scene rect when operating on large scenes.

来自 Qt Docs(强调我的):

This property holds the scene rectangle; the bounding rectangle of the scene

The scene rectangle defines the extent of the scene. It is primarily used by QGraphicsView to determine the view's default scrollable area, and by QGraphicsScene to manage item indexing.

If unset, or if set to a null QRectF, sceneRect() will return the largest bounding rect of all items on the scene since the scene was created (i.e., a rectangle that grows when items are added to or moved in the scene, but never shrinks).

因此,缩小 sceneRect 的唯一方法是使用 setSceneRect