Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QGraphicsItem incorrect center



  • I can't map text item, to the center of a horizontal line, the center is not correct. Neither i use center from bounding box, it's still incorrect.



  • Can you share your code? It's hard for people to help you without seeing your code



  • @mchinand It's just simple set pos.
    I tried to do it this way, since all those map to functions are some random rubbish.

        QGraphicsLineItem* line = new QGraphicsLineItem(0);
        line->setFlag(QGraphicsItem::ItemIsSelectable, true);
        line->setLine(0, 20, 0, 5);
        line->setPen(QPen(Qt::red));
        line->setPos(50, 50);
        this->addItem(line);
        
        QGraphicsTextItem* text = new QGraphicsTextItem(0);
        text->setFlag(QGraphicsItem::ItemIsSelectable, true);
        text->setPlainText(QString::number(index));
        text->setScale(1);
        text->setDefaultTextColor(qRgb(255, 255, 255));
        text->setPos(line->boundingRect().center().x(), line->boundingRect().center().y());
    

    Of course it doesn't work, inaccurate.

    If i change the origin point, it does almost nothing.
    text->setTransformOriginPoint(text->boundingRect().center().x(), text->boundingRect().center().y());

    This Qt system is so frustrating and overcomplicated.


  • Lifetime Qt Champion

    Hi,

    You don't seem to take into account the width of your text item when setting its position.



  • @Loc888 said in QGraphicsItem incorrect center:

    line->boundingRect().center().x()

    boundingRect().center() is in line item coordinates. You need to map it to scene coordinates, in order to get the real point, where you want to move your text in your scene

    ... and no, these functions are not rubbish, if used correctly ;-)



  • @Pl45m4 Then how to set the data they return? They return qpolygonf, idk how to set the x and y from it.



  • Given a QPointF, mapToScene returns a QPointF. https://doc.qt.io/qt-5/qgraphicsitem.html#mapToScene



  • @Loc888

    You looked at the wrong function signature.
    mapToScene is overloaded multiple times.
    The QPolygonF returning function (that takes a QRect) is the wrong one in your case.
    There is one to map QPointFs.

    There is also:

    qreal QPointF::x() const (same with y()) to get (X,Y) separately.



  • @Pl45m4 Doesn't work what so ever comeone..

        QPointF pp = text->mapToScene(QPointF(line->pos().x(), line->pos().y()));
        text->setPos(pp);
    

    Horrible.



  • @Loc888

    I thought you want to display the text centered to your line item?
    Just X and Y alone will take the top left corner of your item, not the center.

    Come on, it's not that hard :)
    You have to do the math on your own ( how and where to place your item and what points you need).
    All functions work as intended and return what they should.

    This might help, if you haven't seen it before:

    https://doc.qt.io/qt-5/graphicsview.html#the-graphics-view-coordinate-system

    There is also this
    (https://doc.qt.io/qt-5/qrectf.html#moveCenter)
    to move the center of a QRectF to a certain point.



  • @Pl45m4 Can't use that moveTocenter, unapplicable.



  • @Loc888

    Because it's textItem->boundingRect().moveCenter(....)

    I've made an example:

    CenterItem.gif

    void MainWindow::centerItems()
    {
        auto textItem = ui->graphicsView->scene()->items().at(0);
        auto lineItem = ui->graphicsView->scene()->items().at(1);
        if(textItem == nullptr || lineItem == nullptr)
            return;
    
        QPointF center = lineItem->boundingRect().center();
    
        QPointF newPoint(lineItem->mapToScene(center).x() - (textItem->boundingRect().width() / 2),
                         lineItem->mapToScene(center).y() - (textItem->boundingRect().height() / 2));
        textItem->setPos(newPoint);
    
    }
    

    To use the boundingRect directly (moveCenter) you have to call prepareGeometryChange which I can't when being inside MainWindow. It is possible that way, but you don't need to do that.
    This would save you from calculating the new point, since pos is always in Item-Coordinates and it's the top-left point, not the center.



  • @Pl45m4 I fixed it with the easier way, i just subtracted the centers in setPos, since it moves it to the topRight corner. The issue was caused by scaled()... I guess it mess up the center/origin, whatever it was. After i removed it, everything is correct.


Log in to reply