I need to create text elements with the exact width and height of the text content .
Text height is the most important requirement.
The position of the text should relate to the text itself.
I should also be able to place it on canvas in the exact place.
Assuming a (printed) canvas (on a larger QGraphicsScene ), say 5 inches wide and 1 inch high, my text should be able to stretch the upper lower left right corner and be placed on the canvas, and not partially.
I will subclass QGraphicsTextItem for my item type. I resize it using QTransform() to the required size in inches or mm or in pixels (72 * inch).
We also set the marker document() to 0, and everything inside (for example, QTextBlockFormat fields) is also equal to 0.
I implemented setItemSize(QSizeF sz) (with sz in pixels) which resizes the QGraphicsTextItem as needed.
Sz is initialized using the bounding box element.
Assuming no wrap, single-line text (multi-line can be resolved separately after fixing this problem).
When adding an element to the canvas, I still see the upper and lower margins - and this depends on the font choice.
I drew a rectangle around the element to see it.
The upper / lower distances depend on the font selection.
I tried using font metrics to determine these distances (in paint() I drew lines to try to determine the position and the rectangle at which the text fits).
I would be glad to at least determine the correct size for use in uppercase, without accents or special character fonts (this would be the beginning, although naturally I would need to use any characters). <b> But at least somehow determine the size and position (relative to the (0,0) element) of the text content even in the simplest case .....
Font taps tightBoundingRect() seem to be the most accurate in size, but it seems impossible to determine its position so that I can somehow properly create my objects and possibly resize / shift them correctly to fit on the canvas.
Here are some examples of my struggle to determine at least the exact size and position of the text relative to the (0,0) element (provided that as soon as I do this, I can expose this information on the street or enable a shift in the transformation of the object when resizing).
Please note that the size of text advertised with font labels does not always cover the text, and for different fonts I canโt position a hard bounding box (magenta) around the text itself. (I made a few guesses, the code below is just one - the lines are trying to show different sizes of font metrics).

Above were experiments with the drawing function of a text element that inherits QGraphicsTextItem :
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { // draw text QGraphicsTextItem::paint(painter, option, widget); QPen p; p.setWidthF(0); QFontMetricsF fm(this->font()); qreal ascent = fm.ascent(), descent = fm.descent(), hheight = fm.height(); QRectF r = QGraphicsTextItem::boundingRect(); QRectF rFont= fm.tightBoundingRect(toPlainText()); qreal xmax = r.right(); painter->save(); painter->setBrush(Qt::NoBrush); // where is "ascent + descent" p.setColor(Qt::green); painter->setPen(p); painter->drawLine(QPointF(2, ascent), QPointF(2, ascent + descent)); painter->drawLine(QPointF(2, ascent + descent), QPointF(xmax/2, ascent + descent)); // where is "height" p.setColor(Qt::red); painter->setPen(p); painter->drawLine(QPointF(xmax/2, 0), QPointF(xmax/2, hheight)); painter->drawLine(QPointF(xmax/2, ascent + descent), QPointF(xmax, ascent + descent)); // where is "ascent" p.setColor(Qt::yellow); painter->setPen(p); painter->drawLine(QPointF(6, 0), QPointF(6, ascent)); painter->drawLine(QPointF(6, ascent), QPointF(xmax, ascent)); // something that may look like top of the text p.setColor(Qt::blue); painter->setPen(p); qreal yyy = ascent + rFont.y() + 1; painter->drawLine(QPointF(5, yyy), QPointF(xmax, yyy)); // this should be useful... should be the natural offset qreal yoffset = (r.height() - rFont.height()) / 2; // qDebug() << yoffset << r << rFont; //qreal y0 = (r.height() - fm.height())/2; p.setColor(Qt::darkGreen); painter->drawEllipse(10, yoffset, 1, 1); // where is the font rect p.setColor(Qt::magenta); painter->setPen(p); yoffset = (r.height() + rFont.height()) / 2; painter->translate(0, yoffset); painter->drawRect(rFont); painter->restore(); }
I also tried not to use QGraphicsTextItem , but I will draw the text inside the rectangle. The same thing is happening.
(Qt 4.7 - 5.x)