首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QFontMetrics在行之间留出额外的空间

QFontMetrics在行之间留出额外的空间
EN

Stack Overflow用户
提问于 2022-10-29 14:57:12
回答 1查看 47关注 0票数 0

我试图用PySide6的QPainterQFontMetrics绘制多个文本段落。我想用相同的间距画他们,如果我把他们都画成一个单一的文本,但是行距不太正确。

在下面的例子中,字体度量表示字体的行距是17。当我测量一行文本时,边框实际上是17像素高。然而,当我测量两行文本时,边框是35像素高,而不是34像素。额外的像素来自哪里,我能在字体或字体度量的某些属性上看到它吗?

代码语言:javascript
复制
from PySide6.QtGui import QFont, QFontMetrics
from PySide6.QtWidgets import QApplication

app = QApplication()
font = QFont()
metrics = QFontMetrics(font)
print(metrics.lineSpacing())  # 17
print(metrics.boundingRect(0, 0, 100, 100, 0, 'A').height())  # 17
print(metrics.boundingRect(0, 0, 100, 100, 0, 'A\nB').height())  # 35 != 17 * 2
print(metrics.leading())  # 0
print(metrics.ascent())  # 14
print(metrics.descent())  # 3

顺便说一句,它并不总是额外的一个像素。如果我使字体变大,额外的空间就会增加。

更新

我以为我已经用音乐人的建议QFontMetrics转换到QFontMetricsF来解决这个问题了,但还是有区别的。

代码语言:javascript
复制
from PySide6.QtCore import QRectF
from PySide6.QtGui import QFont, QFontMetricsF
from PySide6.QtWidgets import QApplication

app = QApplication()
font = QFont()
metrics = QFontMetricsF(font)
print(metrics.height())  # 16.8125
print(metrics.boundingRect(QRectF(0, 0, 100, 100),
                           0,
                           'A').getCoords())  # (0.0, 0.0, 9.9375, 16.8125)
print(metrics.boundingRect(QRectF(0, 0, 100, 100),
                           0,
                           'A\nB').getCoords())  # (0.0, 0.0, 9.9375, 34.8125)
# Note the height of that rect doesn't match the next calculation.
print(metrics.height() + metrics.lineSpacing())  # 34.046875

# I can't see any combination of these numbers that makes 34.8125
print(metrics.lineSpacing())  # 17.234375
print(metrics.leading())  # 0.421875
print(metrics.ascent())  # 13.984375
print(metrics.descent())  # 2.828125
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-29 21:10:05

首先,字体度量的边框的高度并不取决于所使用的字符,而是取决于字体规范。

两行文本没有单行边框的height()的两倍:相反,您必须考虑lineSpacing()

在实践中,圆角的高度通常是以下的总和:

或类似地,以下两者之和:

注意,很明显,行数取决于输入文本和给定的选项,例如,如果启用了word包装,并且任何源行都不适合给定的源矩形。

还要考虑的是,大多数字体都是矢量的,这意味着它们的坐标和度量是成比例的,并且是浮点值。相反,由于简单和优化的原因,QFontMetrics使用整数值,因此在点大小不提供四舍五入值的情况下,可能会得到不一致的结果:非整数通常是“泛”的(如python中的int() )。

在您的示例中,leading可能超过0(但仍然小于1),因此无法得到上述高度的适当和。

具体来说,QFontMetrics.boundingRect()返回由计算格式文本的QRectF.toAlignedRect()生成的QRect,该文本始终是“完全包含此矩形的最小可能整数矩形”。

如果需要获得精确的坐标,则需要使用QFontMetricsF,这是默认基本QFontMetrics的浮点对应。

也就是说,如果您计划使用QPainter绘制格式化文本,那么可以考虑使用QTextDocument或至少使用QTextLayout,这与标准的Qt文本绘图是一致的,并且通常更快、更可靠和“更简单”(嗯,一旦您了解了它)。虽然它看起来比需要的要复杂一些,但它实际上是Qt在调用boundingRect()时所做的,所以如果您需要定制绘图,那么QTextLayout选项实际上更好,特别是如果您可以将它与一些智能缓存(参见QPicture)结合起来,以避免常见的python瓶颈。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74246330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档