How to rotate selected QGraphicsItems around the selection center?

半世苍凉 提交于 2019-12-10 11:35:03

问题


I would like to implement rotation of selected items.

I have noticed that there are 2 functions - rotate() which performs an immediate action but does not save the rotation on the item - and setRotation(), which stores rotation() (though it requires a repaint causing event).

If I select a single item and rotate it, I can set

selectedItem->setRotation(selectedItem->rotation() + deg);

This allows the item to store its rotation, and when I need to copy it to another scene, the item retains its rotation information. So it is what I need.

Trying to rotate multiple selected items though,

foreach(QGraphicsItem *selectedItem, scene()->selectedItems())
{
    if(selectedItem->flags() & QGraphicsItem::ItemIsMovable)
    {
        selectedItem->setRotation(selectedItem->rotation() + deg);
    }
}
viewport()->update();
foreach(QGraphicsItem *selectedItem, scene()->selectedItems())
{
    qDebug("%f", selectedItem->rotation());
}

This causes items to rotate around their own center. It is required that items rotate around the center of selection. Everything else works though - items will have a rotation that can be used later. (shown by qDebug)

To get items to rotate around the selection center:

I have tried to group, rotate, ungroup.

QGraphicsItemGroup* g = scene()->createItemGroup(scene()->selectedItems());
foreach(QGraphicsItem *selectedItem, scene()->selectedItems())
{
    if(!(selectedItem->flags() & QGraphicsItem::ItemIsMovable))
        g->removeFromGroup(selectedItem);
}
g->setRotation(g->rotation() + deg);
scene()->destroyItemGroup(g);
viewport()->update();
foreach(QGraphicsItem *selectedItem, scene()->selectedItems())
{
    qDebug("%f", selectedItem->rotation());
}

This seems to do exactly what I want - apparently.
But copying the items to another scene, the items do not have rotation (does it have another transform ? It doesn't seem like it).
The qDebug doesn't show anything - as if items have disappeared from selection, but they still show selection rectangle. (I don't clear selection)
Pressing on rotate button doesn't repeat rotation. I must unselect each item, then reselect to get rotation again.
Also - even though I remove locked items - they still rotate. (why ??)
So it just doesn't work.

Creating a transformation instead of rotation... I would need to set the center of transformation to the center of selection. Trying

QPointF origin = scene()->selectedItems().???
QPointF origin = scene()->selectionArea().???
QPointF origin = scene()->selectionArea().boundingRect().center();  // shows (0, 0)

If I do know where the center is, I can try:

// hacky till i figure out
QPointF origin(0,0);
foreach(QGraphicsItem *selectedItem, scene()->selectedItems())
{
    origin.setX(origin.x() + selectedItem->pos().x());
    origin.setY(origin.y() + selectedItem->pos().y());
}
int selSize = scene()->selectedItems().size();
origin.setX(origin.x()/selSize);
origin.setY(origin.y()/selSize);
qDebug("%f %f", origin.x(), origin.y());  // I don't know really if this is the center

foreach(QGraphicsItem *selectedItem, scene()->selectedItems())
{
    if(selectedItem->flags() & QGraphicsItem::ItemIsMovable)
    {
        QPointF origin1 = selectedItem->mapFromScene(origin);

        selectedItem->setTransform(selectedItem->transform().
                                   translate(origin1.x(), origin1.y()).
                                   rotate(deg).
                                   translate(-origin1.x(), -origin1.y()));
    }
}

Big improvement .. items rotate as a group... but for some reason after unselecting, and trying to rotate an individual item, it retains previous center of rotation...

How can I do this rotation ?


回答1:


You need to rotate and move each item individually, so that they can be later moved to another scene independently. You can manually calculate new rotations and positions:

void Form2::on_rotate_clicked() {
  QRectF rect;
  foreach(QGraphicsItem* item, scene->selectedItems()) {
    rect |= item->mapToScene(item->boundingRect()).boundingRect();
  }
  QPointF center = rect.center();
  qreal angle = 10;
  QTransform t;
  t.translate(center.x(), center.y());
  t.rotate(angle);
  t.translate(-center.x(), -center.y());
  foreach(QGraphicsItem* item, scene->selectedItems()) {
    item->setPos(t.map(item->pos()));
    item->setRotation(item->rotation() + angle);
  }
}


来源:https://stackoverflow.com/questions/30670137/how-to-rotate-selected-qgraphicsitems-around-the-selection-center

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!