将顶级对象相对于另一个定位

时间:2015-06-14 07:30:57

标签: c++ qt

我需要定位一个顶级对象,使其始终保持在相对于另一个顶级对象的位置。例如,下图中的矩形应该贴在"前面"椭圆:

correct positioning example

旋转180度时,它应如下所示:

correct positioning example rotated 180 degrees

相反,矩形的位置不正确:

incorrect positioning

请运行下面的示例(使用QGraphicsScene仅用于演示目的,因为实际用例在物理学中)。

#include <QtWidgets>

class Scene : public QGraphicsScene
{
    Q_OBJECT
public:
    Scene()
    {
        mEllipse = addEllipse(0, 0, 25, 25);
        mEllipse->setTransformOriginPoint(QPointF(12.5, 12.5));

        QGraphicsLineItem *line = new QGraphicsLineItem(QLineF(0, 0, 0, -12.5), mEllipse);
        line->setPos(12.5, 12.5);

        mRect = addRect(0, 0, 10, 10);
        mRect->setTransformOriginPoint(QPointF(5, 5));

        line = new QGraphicsLineItem(QLineF(0, 0, 0, -5), mRect);
        line->setPos(5, 5);

        connect(&mTimer, SIGNAL(timeout()), this, SLOT(timeout()));
        mTimer.start(5);
    }

public slots:
    void timeout()
    {
        mEllipse->setRotation(mEllipse->rotation() + 0.5);

        QTransform t;
        t.rotate(mEllipse->rotation());

        qreal relativeX = mEllipse->boundingRect().width() / 2 - mRect->boundingRect().width() / 2;
        qreal relativeY = -mRect->boundingRect().height();

        mRect->setPos(mEllipse->pos() + t.map(QPointF(relativeX, relativeY)));
        mRect->setRotation(mEllipse->rotation());
    }

public:
    QTimer mTimer;
    QGraphicsEllipseItem *mEllipse;
    QGraphicsRectItem *mRect;
};

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    QGraphicsView view;
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    view.setScene(new Scene);
    view.resize(200, 200);
    view.show();

    return app.exec();
}

#include "main.moc"

请注意,矩形的位置并不总是相同,但它应始终保持在相对于椭圆的相同位置。例如,它可能从这个位置开始:

alternative positioning example

但它应该在旋转时保持相对位置:

alternative positioning example rotated 180 degrees

1 个答案:

答案 0 :(得分:2)

如果您希望两个对象保持相同的相对位置,则需要围绕同一原点旋转。

此处您的圆圈围绕其中心(点12.5,12.5)旋转,但您的矩形围绕另一个原点(5,5)而不是圆圈的中心(12.5,12.5)旋转。

如果您修复原点,它将按预期工作:

mRect->setTransformOriginPoint(QPointF(12.5, 12.5));

即使矩形以偏移开始:

mRect = addRect(-10, 0, 10, 10); // Start 10 units to the left

Screenshot of the result