QGraphicsItemGroup :: boundingRect()没有更新

时间:2018-03-08 01:00:43

标签: c++ qt qgraphicsview qgraphicsscene qgraphicsitem

我一直在尝试使用QGraphicsItemGroup来获取一组QGraphicsItem *的边界矩形。在我看来,当我将所有项目插入到组中时,正确确定了边界矩形;但是如果我然后移动组中的项目,则边界矩形不会更新以包含我期望的移动项目。我无法在文档中找到关于我所看到的是否是正确行为的指示;我的猜测是,我误解了QGraphicsItemGroup的工作方式或误用了它

我一直用来测试的一个例子:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTransform>
#include <QGraphicsEllipseItem>
#include <QDebug>
#include <QTimer>

#include <cmath>

const double pi = 3.14;

QTransform rotation(double degrees)
{

    double a    = pi/180 * degrees;
    double sina = sin(a);
    double cosa = cos(a);

    return QTransform(cosa, sina, -sina, cosa, 0, 0);
}

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

    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->show();

    //Shouldn't execute until after window.show() and application.exec()
    //are called
    QTimer::singleShot(1, this, &MainWindow::build);
}

void MainWindow::build()
{
    QGraphicsEllipseItem* el1 = scene->addEllipse(-5, -5, 10, 10);
    scene->addLine(0, 0, 0, 10)->setParentItem(el1);

    QGraphicsEllipseItem* el2 = scene->addEllipse(-5, -5, 10, 10);
    scene->addLine(0, 0, 0, 10)->setParentItem(el2);

    QGraphicsEllipseItem* el3 = scene->addEllipse(-5, -5, 10, 10);
    scene->addLine(0, 0, 0, 10)->setParentItem(el3);

    QGraphicsEllipseItem* el4 = scene->addEllipse(-5, -5, 10, 10);
    scene->addLine(0, 0, 0, 10)->setParentItem(el4);

    QGraphicsItemGroup* group = new QGraphicsItemGroup;
    group->addToGroup(el1);
    group->addToGroup(el2);
    group->addToGroup(el3);
    group->addToGroup(el4);

    scene->addItem(group);

    scene->addRect(group->boundingRect());

    QTransform translate2(1, 0, 0, 1, 10, 10);
    QTransform t2 = /*rotation(45) **/ translate2;
    el2->setTransform(t2);

    QTransform translate3(1, 0, 0, 1, 20, 20);
    QTransform t3 = /*rotation(-45) **/ translate3 * t2;
    el3->setTransform(t3);

    QTransform translate4(1, 0, 0, 1, 20, -20);
    QTransform t4 = translate4 * t3;
    el4->setTransform(t4);

    qDebug() << t4.dx() << t4.dy() << atan2(t4.m12(), t4.m22())*180/pi;
    QTransform t4i = t4.inverted();
    qDebug() << t4i.dx() << t4i.dy() << atan2(t4i.m12(), t4i.m22())*180/pi;

    scene->addRect(group->boundingRect());
}

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

显示的最终场景如下所示

实际结果

但是,我期待这样的事情,第一个boundingRect有一个小盒子,第二个有一个更大的盒子

预期结果

我误解了QGraphicsItemGroup是如何工作的,还是我错误地使用它?

Qt版本:5.10

操作系统:Ubuntu 16.04

编译器GCC 5.4

2 个答案:

答案 0 :(得分:0)

QGraphicsItemGroup文档似乎没有提到这一点,但它只会在视图后重新计算boundingRect的{​​{1}}并显示QGraphicsItemGroup

之后添加项目

QGraphicsScene

结果在该组的所有成员的边界矩形

enter image description here

答案 1 :(得分:0)

boundingrect 仅在 additem 时更新。因此必须使用方法 childrenBoundingRect() 而不是 boundingRect()。 在 QGraphicsItemGroup 的单独子类中,比如 MyQGraphicsItemGroup,我们可以重载方法 virtual QRectF boundingRect() const override 以便调用 childrenBoundingRect()

QRectF MyQGraphicsItemGroup::boundingRect() const
{
   // must be overloaded, otherwise the boundingrect will only be actualized on
   // additem is actualized. This leads to the fact that the boundingrect 
   // will not close around the word items after e.g., moving them. 
   return childrenBoundingRect();
}