为何同一QTreeView部件的QFont与QFontInfo的family属性取值存在差异?
测试现象
在QTreeView控件上执行如下打印代码:
qDebug() << "ff1" << m_titleTreeView->font().family(); qDebug() << "ff2" << m_titleTreeView->fontInfo().family();
实际输出结果为:
ff1 "Verdana" ff2 "Noto Sans"
原本预期两个接口的返回结果应当完全一致,实际测试发现除字体族名称字段外,像素大小、字重、点大小等属性的取值都非常接近,测试环境为Qt 5.11.0、GCC编译环境。
差异产生的核心原因
两个接口的设计定位完全不同,返回的字体信息本质不属于同一份数据:
font()接口返回的是控件存储的原始期望字体对象。这个字体对象是通过应用全局配置、父控件属性继承、或代码显式调用setFont()设置进去的,全程不会经过系统字体匹配引擎的修改。你给控件设置的字体名是什么,该接口就会原封不动返回什么,哪怕当前系统根本没有安装这款字体。fontInfo()接口返回的是控件实际渲染时使用的生效字体元信息。Qt在真正绘制控件内容前,会将存储的原始字体对象交给平台的字体匹配引擎做兜底校验:如果原始设置的字体在当前系统不存在、或无法覆盖需要渲染的字符范围,引擎就会按照原始字体的字号、字重等参数,匹配风格最接近的系统可用字体完成替换。该接口返回的就是替换完成后,真正参与绘制的字体的属性信息。
对应到本次测试的场景:结合返回的Noto Sans字体判断,当前运行的Linux类系统没有预装Verdana字体,Qt的字体匹配引擎在执行实际渲染时,选择了风格、参数最接近的Noto Sans作为替代字体。这也解释了为什么两个接口拿到的字体族名称不一致,但字号、字重等参数高度接近——匹配引擎会严格按照原始字体的参数做对齐替换。
补充说明
- 这类由字体替换导致的接口返回值差异,在Linux平台出现的概率远高于Windows。Windows系统默认预装了Verdana等通用字体,字体匹配流程很少触发替换逻辑,两个接口的返回值经常完全一致,容易让开发者误以为二者功能等价。
- 在Qt 5.11的实现逻辑中,只要触发了字体替换流程,
fontInfo()返回的字体族名称就是实际匹配生效的字体名,不会保留最初设置的原始字体名。
内容的提问来源于stack exchange,提问作者user10609288
相关产品推荐
相关产品推荐

