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

QGraphicsItem & drawText - boundingRect draw errors & text anchor



  • Hey

    I'm trying to create a custom graphics element that would have a circle and a text next to it.

    I have 2 problems.

    1. The text does not redraw properly, mostly because the boundingBox returns only the circle and it does not include the text - how can I calculate the extra space I need for the text so that it draw properly when item is being dragged/translated/moved ?

    2. How can I tell text to be anchored to the left/right/upper/other corner. So that if I have a circle the text would be painted to the right of it (this is this way now it seems fine) but how can I tell the text to be anchored at the right side(of text, where it ends) so that the text is tho the left of circle?

    I draw my text this way

    painter->drawEllipse(mRect);
    painter->drawText(mTextPosition,mDescription);
    

    Regards
    Dariusz
    TIA


  • Moderators

    @Dariusz said in QGraphicsItem & drawText - boundingRect draw errors & text anchor:

    I draw my text this way
    painter->drawEllipse(mRect);
    painter->drawText(mTextPosition,mDescription);

    you need to show a little more code to give exact help



  • @raven-worx

    Hey

    Humh here is a little more, a temporary work around I found was to add extra larger rect item to boundingBox return function. That seems to be used as paint area. But now I can drag by text which is not too much desired. Also the box is only as wide as widget and not as text. So It will cause an issue in long term. In a way I need to have a flipped L shape bounding box ? Not sure...

    void icNodeBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
        //painter->drawRoundedRect(mIcRect, 10, 10);
        //painter->drawText(mIcRect.width() / 2 - mNameSize, 0, mIcName);
        painter->setFont(mIcNameFont);
        painter->drawText(0, -5, mIcName);
    
        painter->setBrush(QBrush(QColor(150, 150, 150, 255)));
        painter->drawRoundedRect(mIcRect, 30, 30);
        painter->setBrush(QBrush(QColor(75, 75, 75)));
        painter->drawRoundedRect(QRect(mIcRect.x() + 5, mIcRect.y() + 5, mIcRect.width() - 10, mIcRect.height() - 10), 25, 25);
    
        if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus)) {
            //qt_graphicsItem_highlightSelected(this, painter, option);
        }
    }
    
    QRectF icNodeBase::boundingRect() const { // const in function mean that it will not change anything? maybe.
        qreal penWidth = 1;
        return mIcBoundingRect;// + fontRect;
        return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
                      200 + penWidth, 200 + penWidth);
    }
    
        mIcRect.setHeight(60 + rectHeightMultiplier * 20 + 40);
        mIcRect.setWidth(150);
    
        mIcBoundingRect = mIcRect;
        mIcBoundingRect.setTop(-30); // -30 to add the text above the item.
    


  • @Dariusz

    1. you need to add the bounding box of your text to the bounding box of your circle or whatever.
    2. you position your text at the correct place in relation to the circle or whatever. Which you obviously know the size and position of.
      Here is a simple graphics item as an example, I am sure you can understand what is going on and can adapt it for your needs.
      The text should draw correctly and you should be able to drag it around if you need to do that.
      If you want to more sophisticated interaction or clipping other graphics items you should implement the shape() function.
    class textThing : public QGraphicsItem
    {
    public:
        explicit textThing(QGraphicsItem * parent = 0);
    
        QRectF boundingRect() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    
    };
    
    textThing::textThing(QGraphicsItem * parent) : QGraphicsItem(parent)
    {
        setFlags(flags() | QGraphicsItem::ItemIsMovable);
        setAcceptedMouseButtons(Qt::AllButtons);
        setAcceptHoverEvents(true);
    }
    
    QRectF textThing::boundingRect() const
    {
        QRectF rect1(0,0,50,50);
        QString text("Hello World");
        QFont currentFont = scene()->font();
        QFontMetricsF fontMetrics(currentFont);
        QRectF rect2 = fontMetrics.boundingRect(text).translated(50,25);
    
        return rect1.united(rect2);
    }
    
    void textThing::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        QString text("Hello World");
        QPen pen2(QBrush(QColor(0,0,0)),2,Qt::SolidLine,Qt::SquareCap,Qt::MiterJoin);
        painter->setPen(pen2);
        painter->drawRoundedRect(0,0,50,50,10,10);
        painter->drawText(50, 25, text);
    }
    


  • @Dariusz

    Hey

    Is this issue solved for you? If so please mark it a solved so others with the same question can benefit.
    Thanks


Log in to reply