QFontMetrics 相关学习,如有错误欢迎指出~
一、 简介
1. 介绍
QFontMetrics 是 Qt 中用于获取字体度量信息的核心类,它提供了精确计算文本尺寸和布局所需的方法。
2. 作用
-
计算文本渲染后的物理尺寸(宽度、高度)
-
获取字体属性(行高、基线位置、字符间距等)
-
支持高级文本操作(省略文本、边界框计算)
3. 创建方式
// 方式1:基于字体创建
QFont font("Arial", 12);
QFontMetrics fm(font);
// 方式2:基于控件字体创建(推荐)
QFontMetrics fm(widget->font());
二、 常用方法及示例
1. 基本尺寸计算

2. 基线相关

基线图示:
ascent
↑
┌─────┐ (字符顶部)
│ A │
└─────┘ (基线)___
↓ | descent
┌─────┐ (字符底部)
3. 高级度量
// 1. 字符边界框(含装饰/溢出部分)
QRect bbox = fm.boundingRect("Text");
// 2. 紧致边界框(精确像素包围)
QRect tight = fm.tightBoundingRect("Text");
// 3. 省略文本(超出宽度时显示...)
QString elided = fm.elidedText(
"Long text here",
Qt::ElideRight, // 省略位置
maxWidth // 最大像素宽度
);
4. 字符级度量
// 单个字符宽度
int w = fm.horizontalAdvance('X');
// 左/右bearing(字符溢出部分)
int leftOverlap = fm.leftBearing('T'); // 可能为负
int rightOverlap = fm.rightBearing('j');
三、关键特性
1. 单位系统
-
所有单位均为像素(与设备无关)
-
基于当前字体设置(字号、粗体、斜体等)
2. 多语言支持
-
自动处理复杂脚本(阿拉伯语、印度语系)
-
支持代理对(Surrogate Pairs,如 emoji 👋)
3. 性能优化
-
缓存机制(重复查询高效)
-
轻量级对象(可临时创建)
四、使用场景
1. 文本对齐
// 居中绘制文本
void Widget::paintEvent(QPaintEvent*) {
QPainter p(this);
QString text = "Hello";
int textWidth = fm.horizontalAdvance(text);
int x = (width() - textWidth) / 2; // 水平居中
int y = fm.ascent() + 10; // 垂直基线位置
p.drawText(x, y, text);
}
2. 布局计算
// 动态调整控件大小
label->setFixedWidth(fm.horizontalAdvance("Longest Item") + 20);
3. 文本省略
// 表格单元格内省略
QString itemText = model->data(index).toString();
QString displayText = fm.elidedText(itemText, Qt::ElideRight, cellWidth);
五、注意事项
1. 字体变化
字体修改后需重新创建 QFontMetricsF 对象
2. 缩放场景
在高DPI屏上需结合 devicePixelRatio计算
3. 替代方案
- QFontMetricsF:浮点版本(更精确)
- QTextLayout:复杂文本布局
六、实例
void measureText(const QString& text, const QFont& font) {
QFontMetrics fm(font);
qDebug() << "Text:" << text;
qDebug() << "Width:" << fm.horizontalAdvance(text) << "px";
qDebug() << "Height:" << fm.height() << "px";
qDebug() << "Ascent:" << fm.ascent() << "px";
qDebug() << "Descent:" << fm.descent() << "px";
qDebug() << "Bounding Rect:" << fm.boundingRect(text);
}
/*
输出
Text: "Qt"
Width: 24 px
Height: 15 px
Ascent: 12 px
Descent: 3 px
Bounding Rect: [0, -11, 24, 15]
*/
583

被折叠的 条评论
为什么被折叠?



