简体   繁体   中英

Positioning a top-level object relative to another

I need to position a top-level object so that it always remains in a position relative to another top-level object. As an example, the rectangle in the image below should stick to the "front" of the ellipse:

正确的定位示例

When rotated 180 degrees, it should look like this:

正确的定位示例旋转了180度

Instead, the position of the rectangle is incorrect:

定位不正确

Please run the example below (the use of QGraphicsScene is for demonstration purposes only, as the actual use case is in physics).

#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"

Note that the position of the rectangle is not always the same, but it should always remain in the same position relative to the ellipse. For example, it may start off in this position:

替代定位示例

But it should stay in that relative position when rotated:

替代定位示例旋转180度

If you want the two objects to keep the same relative position, they need to rotate around the same origin point.

Here your circle rotates around its center (the point 12.5, 12.5), but your rectangle rotates around another origin (5,5) instead of the circle's center (12.5, 12.5).

If you fix the origin, it'll work as you expect:

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

Even if the rectangle starts off with an offset:

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

结果截图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM