我需要创建具有精确宽度和高度的文本内容的文本项。
文字的高度是最重要的要求。
文本的位置应该相对于文本本身。
我还必须能够将它放置在画布上的确切位置。
假设一个(可打印的)画布(在较大的QGraphicsScene
)上,比如 5 英寸宽和 1 英寸高,我的文本应该能够从上到下从左到右拉伸 - 并放置在画布上,而不是部分地分开。
我正在QGraphicsTextItem
为我的项目类型分类。我正在调整它的大小,使用QTransform()
, 到所需的大小 - 以英寸或毫米或像素(72 * 英寸)为单位。
还将边距设置document()
为 0,内部的任何内容(如QTextBlockFormat
边距)也设置为 0。
我已经实现了一个setItemSize(QSizeF sz)
(以像素为单位的 sz),它可以QGraphicsTextItem
根据需要调整大小。
使用项目边界矩形初始化 sz。
假设没有换行,单行文本(一旦这个问题得到解决,多行可以单独解决)。
将项目添加到画布时,我仍然看到顶部和底部边距 - 这取决于字体选择。
我在项目周围画了一个矩形来查看它。
顶部/底部距离取决于字体选择。
我尝试使用字体度量来确定这些距离(paint()
我一直在画线以尝试确定文本适合的位置和矩形)。
我很高兴至少能够确定正确的大小以用于大写,没有重音或特殊字符字体(这将是一个开始,尽管我自然需要能够使用任何字符)。
但至少有某种方法可以确定文本内容的大小和位置(相对于项目的(0,0)),即使在最简单的情况下......
字体指标tightBoundingRect()
似乎是最准确的大小,但似乎无法确定它的位置,以便我可以以某种方式正确创建我的项目,并可能正确调整大小/移动它们以适合画布。
以下是我努力确定相对于项目的 (0,0) 的文本的至少确切大小和位置的一些示例(假设一旦我这样做,我就能够将该信息暴露给外部或包括转变在调整大小的项目变换中)。
请注意,字体度量所宣传的文本大小并不总是覆盖文本,并且对于不同的字体,我无法将紧密的边界矩形(洋红色)定位在文本本身周围。(我做了多次猜测,下面的代码只是一个 - 这些行试图显示不同的字体度量大小)。
以上是文本项继承绘制功能的实验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();
}
我也尝试过不使用QGraphicsTextItem
,而是在矩形内绘制文本。同样的事情也会发生。
(Qt 4.7 - 5.x)