缩放视图时如何保持QGraphicsItem的大小和位置?

cod*_*eup 5 c++ qt qgraphicsitem

我在 QGraphicsScene 中有一些 QGraphicsItems,它们在缩放时应保持相同的大小和位置。我尝试过 QGraphicsItem::ItemIgnoresTransformations 但事实证明这些项目的位置错误。下面是示例代码:

我像这样子类化了 QGraphicsView:

class Graphics : public QGraphicsView
{
public:
    Graphics();
    QGraphicsScene *scene;
    QGraphicsRectItem *rect;
    QGraphicsRectItem *rect2;

protected:
    void wheelEvent(QWheelEvent *event);
};
Run Code Online (Sandbox Code Playgroud)

在它的构造函数中:

Graphics::Graphics()
{
    scene = new QGraphicsScene;
    rect = new QGraphicsRectItem(100,100,50,50);
    rect2 = new QGraphicsRectItem(-100,-100,50,50);
    scene->addLine(0,200,200,0);

    rect->setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
    scene->addItem(rect);
    scene->addItem(rect2);

    setScene(scene);
    scene->addRect(scene->itemsBoundingRect());
}
Run Code Online (Sandbox Code Playgroud)

wheelEvent 虚函数:

void Graphics::wheelEvent(QWheelEvent *event)
{
    if(event->delta() < 0)
        scale(1.0/2.0, 1.0/2.0);
    else
        scale(2, 2);
    scene->addRect(scene->itemsBoundingRect());

    qDebug() << rect->transform();
    qDebug() << rect->boundingRect();
    qDebug() << rect2->transform();
    qDebug() << rect2->boundingRect();
}
Run Code Online (Sandbox Code Playgroud)

原始视图如下所示: 1

以线为路,以直线为符号。缩小时,矩形保持其大小但跳出场景: 2

这应该是矩形的左上角到线的中间。我也对调试信息感到困惑,显示boundingRect和变换保持不变,这似乎没有任何改变!造成这个问题的原因是什么?有什么方法可以解决吗?有人可以帮忙吗?谢谢你!

cod*_*eup 2

抱歉耽搁了,现在我自己解决了这个问题。

我发现QGraphicsItem::ItemIgnoresTransformations只有当您想要粘贴的点位于项目坐标中的 (0,0) 时才有效。您还需要以这种方式手动更新boundingRect。尽管如此,我发现的最好的解决方案是子类 QGraphicsItem 并根据世界矩阵在 Paint() 中设置矩阵。下面是我的代码。

QMatrix stableMatrix(const QMatrix &matrix, const QPointF &p)
{
    QMatrix newMatrix = matrix;

    qreal scaleX, scaleY;
    scaleX = newMatrix.m11();
    scaleY = newMatrix.m22();
    newMatrix.scale(1.0/scaleX, 1.0/scaleY);

    qreal offsetX, offsetY;
    offsetX = p.x()*(scaleX-1.0);
    offsetY = p.y()*(scaleY-1.0);
    newMatrix.translate(offsetX, offsetY);

    return newMatrix;
}
Run Code Online (Sandbox Code Playgroud)

和绘画功能:

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                   QWidget *widget)
{
     QPointF p(left, top);
     painter->setMatrix(stableMatrix(painter->worldMatrix(), p));
     painter->drawRect(left, top, width, height);
}
Run Code Online (Sandbox Code Playgroud)

stableMatrix 的第二个参数是粘着点,在我的示例代码中它位于项目的左上角。您可以根据自己的喜好更改它。效果真的很好!希望这篇文章有帮助:)