【问题标题】:How to rotate selected QGraphicsItems around the selection center?如何围绕选择中心旋转选定的 QGraphicsItem?
【发布时间】:2015-08-20 14:48:27
【问题描述】:

我想实现所选项目的轮换。

我注意到有 2 个函数 - rotate() 执行即时操作但不保存项目的旋转 - 和 setRotation() 存储旋转 ()(尽管它需要重新绘制导致事件)。

如果我选择单个项目并旋转它,我可以设置

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

这允许项目存储它的旋转,当我需要将它复制到另一个场景时,项目会保留它的旋转信息。所以这是我需要的。

尝试旋转多个选定的项目,

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

这会导致项目围绕自己的中心旋转。要求项目围绕选择中心旋转。其他一切都有效 - 项目将有一个可以稍后使用的轮换。 (由 qDebug 显示)

要让项目围绕选择中心旋转:

我尝试过分组、旋转、取消分组。

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

这似乎完全符合我的要求 - 显然。
但是将项目复制到另一个场景,项目没有旋转(它有另一个变换吗?看起来不像)。
qDebug 不显示任何内容 - 好像项目已从选择中消失,但它们仍显示选择矩形。 (我不清除选择)
按下旋转按钮不会重复旋转。我必须取消选择每个项目,然后重新选择才能再次轮换。
另外——即使我移除了锁定的物品——它们仍然会旋转。 (为什么??)
所以它只是不起作用。

创建转换而不是旋转...我需要将转换中心设置为选择中心。尝试

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

如果我知道中心在哪里,我可以试试:

// 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()));
    }
}

重大改进..项目作为一个组旋转...但由于某种原因在取消选择并尝试旋转单个项目后,它保留了先前的旋转中心...

如何进行这种轮换?

【问题讨论】:

    标签: qt rotation selection qgraphicsitem


    【解决方案1】:

    您需要单独旋转和移动每个项目,以便以后可以将它们单独移动到另一个场景。您可以手动计算新的旋转和位置:

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

    【讨论】:

    • 小问题:默认情况下旋转方向是顺时针还是逆时针?每当我使用角度值(0..360)时,我都会顺时针旋转。如果我否定角度,那么我会得到我期望看到的。
    • QTransform 中的旋转是 counterclockwise 用于正角度。但是,这仅适用于standard orientation of axesQGraphicsView中的Y轴默认是向下的,所以旋转方向是翻转的。
    • 我其实知道,甚至用它来翻译,但在轮换的时候完全忘记了。 XD
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多