gpt4 book ai didi

qt - 设置精确高度和宽度的 QGraphicsTextItem 文本内容

转载 作者:行者123 更新时间:2023-12-04 13:23:59 25 4
gpt4 key购买 nike

我需要使用 创建文本项文本内容的精确宽度和高度 .
文字的高度是最重要的要求。
文本的位置应该相对于文本本身。

我还必须能够将它放置在 Canvas 上的确切位置。

假设一个(可打印的) Canvas (在更大的 QGraphicsScene 上),比如 5 英寸宽和 1 英寸高,我的文本应该能够从上到下从左到右拉伸(stretch) - 并被放置在 Canvas 上,而不是部分分开.

我正在分类 QGraphicsTextItem对于我的项目类型。我正在调整它的大小,使用 QTransform() , 到所需尺寸 - 以英寸或毫米或像素 (72*in) 为单位。
同时设置 document()边距为 0,内部的任何内容(如 QTextBlockFormat 边距)也为 0。

我已经实现了 setItemSize(QSizeF sz) (以像素为单位的 sz),调整 QGraphicsTextItem 的大小按要求。
使用项目边界矩形初始化 sz。
假设没有换行,单行文本(一旦这个问题得到解决,多行可以单独解决)。

将项目添加到 Canvas 时,我仍然看到顶部和底部边距 - 这取决于字体选择。
我在项目周围画了一个矩形来查看它。
顶部/底部距离取决于字体选择。

我尝试使用字体度量来确定这些距离(在 paint() 中,我一直在画线以尝试确定文本适合的位置和矩形)。

我很高兴至少能够确定正确的大小以用于大写,没有重音或特殊字符字体(这将是一个开始,尽管我自然需要能够使用任何字符)。
但至少有一些方法可以确定大小和位置 (相对于项目的(0,0))即使在最简单的情况下也是如此.....

字体规范tightBoundingRect()似乎是最准确的尺寸,但似乎不可能确定它的位置,以便我可以以某种方式正确创建我的项目,并可能正确调整它们的大小/移动它们以适合 Canvas 。

以下是我努力确定相对于项目的 (0,0) 的文本的至少确切大小和位置的一些示例(假设一旦我这样做,我就能够将该信息暴露给外部或包括转变在调整大小的项目变换中)。
请注意,字体度量所宣传的文本大小并不总是覆盖文本,并且对于不同的字体,我无法将紧密的边界矩形(洋红色)定位在文本本身周围。 (我做了多次猜测,下面的代码只是一个 - 这些行试图显示不同的字体度量大小)。

enter image description here

以上是继承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)

最佳答案

这不是一个好的解决方案。 这是尝试解决我自己的问题 - 在第一次迭代中 - 使用字体度量设置具有给定宽度和高度的文本。

不好的原因——

  • 即使调整大小后,文本也比预期的要小,我不明白为什么
  • 位置不正确,根据字体样式,文本可以在 Canvas 上方或下方,这意味着它被剪裁了。


  • 我使用从项目边界矩形大小和字体度量边界矩形计算的因子调整它的大小(我使用紧密边界矩形以获得更准确的大小)。
    myText->setItemFontSize(12);   // If I use font metrics I need to reset text size on every change, because resizing loses font info 
    QFontMetricsF fm(myText->font());
    QRectF fmRect = fm.tightBoundingRect(myText.toPlainText().toUpper());
    // without toUpper() the size is too small - even so it is a bit small
    // I read tightBoundingRect is slow - but boundingRect and height and ascent all give values that result in even smaller size
    //qreal absH = fm.ascent();
    qreal absH = fmRect.height();
    qreal absW = fmRect.width();
    qreal absHeightRatio = myText->getItemSize().height() / absH;
    qreal absWidthRatio = myText->getItemSize().width() / absW;

    然后设置大小:
    myText->setItemSize(QSizeF(absWidthRatio * textLength, absHeightRatio * fontHeight));
    // This function scales the `QTransform` on item
    // but since I request a final position dependent on item size
    // (including blank space around it) - it has no chance of being accurate.....
    // This is where my next effort will go, figuring out how to get rid of the fluff
    // around the item inside the scaling

    设置位置的功能:尝试居中文本:
    // leftShift  = 10, rightShift = 10 in example
    myText->setPos(0,0);
    QRectF r = myText->mapToScene(myText->boundingRect()).boundingRect();
    QSizeF sz = r.size();
    qreal w = sz.width();
    qreal h = sz.height();
    qreal cx = (m_docLength - w + leftShift - rightShift)/2 - r.left();
    qreal cy = (m_docHeight - h)/2 - r.top();
    myText->setPos(cx, cy);

    下面的图片适用于 fontHeight = m_docHeight -

    理想的:
    - 文本的整个大小(上升 + 下降)等于文档高度,并且文本基于内容垂直居中
    - 或者大写大小的文本等于文档高度并且下降低于文档(仅基于大写的文本居中) - 根据 QGraphicsTextItem 的方式,这似乎更容易似乎定位它

    实际的:
    - 文本是 更小 无论我使用哪些参数来缩放,并以大写文本为中心

    enter image description here

    如上所示-我不知道如何根据内容垂直居中(因此对于边缘到边缘的文本,下降将适合)-取而代之的是,我真正想要的是边缘到边缘的大写字母,但我似乎无法做到这一点。

    哦,这些是用于 Arial 类型的字体 - 表现最好的字体之一。其他字体在 Canvas 上方或下方到处跳跃。对于某些字体,生成的文本实际上更小——这对我来说是莫名其妙的,因为紧密的边界矩形怎么会小于项目边界矩形......

    就我而言,这仍然是让我的文本接近“真实”大小并放置在与其大小相匹配的 Canvas 上。

    关于qt - 设置精确高度和宽度的 QGraphicsTextItem 文本内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37736412/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com