Group + ungroup QGraphicItems - 在取消分组

时间:2015-08-05 14:43:42

标签: qt grouping transformation qgraphicsitem

我有各种QGraphicsItem的项目,并且想要创建组 我试图了解分组的行为 - 特别是如何正确分组,以便我的项目能够记住分组过程中发生的事情。

我需要在场景坐标中取消组合后的项目的真实位置,旋转和比例。

到目前为止,我想出了如何从组项中检索旋转以传递给子项,但这就​​是全部 - 我不明白位置和缩放是如何工作的。 (我有点理解位置是如何工作的,但不知道如何修复它)

我创建了一个简单的示例来检查值:

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsRectItem>

void dealingWithGroups(QGraphicsScene* s)
{
    QGraphicsRectItem* r0 = new QGraphicsRectItem(0, s); // some subclassed item
    r0->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemStacksBehindParent);
    r0->setRect(QRectF(0,0,100,100));
    r0->setPos(QPointF(100,100));
    r0->scale(0.8, 1.1);
    r0->setSelected(true);

    QGraphicsRectItem* r1 = new QGraphicsRectItem(0, s); // some subclassed item
    r1->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemStacksBehindParent);
    r1->setRect(QRectF(0,0,100,100));
    r1->setPos(QPointF(250,100));
    r1->setRotation(20);
    r1->setSelected(true);

    QString message;

    message = QString("before:\nr0: pos %1 %2 rotation %3 scale %4 %5\nr1: pos %6 %7 rotation %8 scale %9 %10")
            .arg(r0->pos().x()).arg(r0->pos().y()).arg(r0->rotation()).arg(r0->transform().m11()).arg(r0->transform().m22())
            .arg(r1->pos().x()).arg(r1->pos().y()).arg(r1->rotation()).arg(r1->transform().m11()).arg(r1->transform().m22());
    qDebug(qPrintable(message));

    QGraphicsItemGroup* g = new QGraphicsItemGroup(); // actually subclassed
    g->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemStacksBehindParent);
    g->setSelected(true);

    foreach(QGraphicsItem* item1, s->selectedItems())
    {
        //item1->setParentItem(g);  // or
        g->addToGroup(item1);
        item1->setSelected(false);
    }
    message = QString("group before move:\ng: pos %1 %2 rotation %3 scale %4 %5")
        .arg(g->pos().x()).arg(g->pos().y()).arg(g->rotation()).arg(g->transform().m11()).arg(g->transform().m22());
    qDebug(qPrintable(message));

    s->addItem(g);
    g->setPos(300, 200);
    g->setRotation(10);
    g->scale(1.5, 1.8);

    message = QString("group:\ng: pos %1 %2 rotation %3 scale %4 %5")
            .arg(g->pos().x()).arg(g->pos().y()).arg(g->rotation()).arg(g->transform().m11()).arg(g->transform().m22());    
    qDebug(qPrintable(message));

    foreach(QGraphicsItem* item1, s->selectedItems())
    {
        //item1->setParentItem(0);  // or
        QGraphicsItemGroup* groupItem = dynamic_cast<QGraphicsItemGroup*>(item1);
        if(groupItem)
        {
            qreal rot = groupItem->rotation();
            foreach(QGraphicsItem* child, groupItem->childItems())
            {
                child->setRotation(child->rotation() + rot);
                // child->setPos(child->mapFromParent(child->pos())); or something, this doesn't work
            }
            s->destroyItemGroup(groupItem);
        }
    }

    message = QString("after:\nr0: pos %1 %2 rotation %3 scale %4 %5\nr1: pos %6 %7 rotation %8 scale %9 %10")
            .arg(r0->pos().x()).arg(r0->pos().y()).arg(r0->rotation()).arg(r0->transform().m11()).arg(r0->transform().m22())
            .arg(r1->pos().x()).arg(r1->pos().y()).arg(r1->rotation()).arg(r1->transform().m11()).arg(r1->transform().m22());
    qDebug(qPrintable(message));
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);    
    QGraphicsScene s;
    s.setSceneRect(-50, -50, 500, 500);
    QGraphicsView view(&s);
    view.show();
    dealingWithGroups(&s);
    return app.exec();
}

输出:如果我设置旋转,移动,缩放

before:
r0: pos 100 100 rotation 0 scale 0.8 1.1
r1: pos 250 100 rotation 20 scale 1 1
group before move:
g: pos 0 0 rotation 0 scale 1 1
group after setPos:
g: pos 300 200 rotation 10 scale 1.5 1.8
scene size: 3
scene size: 2
after:
r0: pos 421.674 408.522 rotation 10 scale 1.18177 1.94992
r1: pos 643.256 455.407 rotation 30 scale 1.47721 1.77265

所以我看到,在添加所有项目后,该组的位置仍为(0,0)。并且它应用由于组移动和组旋转引起的任何更改,然后根据结束位置给出结果。我不知道规模会发生什么。

我尝试使用

调整位置
child->setPos(child->mapFromParent(child->pos()));

没用。

即使没有移动,看起来物体也会在很大程度上改变位置 - 在视觉上,而不是在群体中心周围旋转; 缩放也似乎关闭了,为什么还有缩放?

我真的需要帮助找出如何在取消组合后获取项目信息,基于受组动作影响的初始位置,轮换和比例。

取消组合后我需要物品的位置,而且我需要真正的比例 - 因为我必须应用我自己的调整大小操作。

项目如何在场景中的某个位置显示,并且具有一定的旋转和缩放,但报告pos()rotation()完全不同?

由于我正在继承我的所有项目 - 包括QGraphicsItemGroup,如果我能理解他们的行为,我可以覆盖分组或取消分组功能。

0 个答案:

没有答案