Qt 5.4.3设置Open Sans为应用主字体时中文显示为空框,fallback字体未生效问题咨询
嘿,这个问题我之前做Qt项目的时候也碰到过!核心原因其实是:你手动通过QFontDatabase::addApplicationFont()添加的字体,并不会自动加入到其他字体的 fallback 链里。哪怕你确认两个字体都加载成功了,Qt默认只会死死盯着你指定的全局字体(Open Sans)来渲染所有字符,一旦遇到它不支持的中文字符,就直接显示空框,根本不会主动去找你加载的WenQuanYi Zen Hei。
给你几个亲测有效的解决办法,按推荐程度排序:
方法一:构造多字体族的全局字体(最推荐)
这是最简单直接的方式,你可以创建一个QFont对象,把Open Sans设为第一优先级,WenQuanYi Zen Hei作为备选,然后设置成全局字体:
QFont appFont; // 字体族列表,优先级从左到右:先试Open Sans,不行就用文泉驿 appFont.setFamilies({"Open Sans", "WenQuanYi Zen Hei"}); appFont.setPointSize(12); qApp->setFont(appFont);
这样Qt渲染字符时,会先尝试用Open Sans处理拉丁字母,遇到它搞不定的中文字符,就自动切换到列表里的下一个字体,完美符合你的需求。
方法二:配置全局字体Fallback规则
如果你想让WenQuanYi Zen Hei成为所有字体的通用 fallback(不止Open Sans),可以用QFontDatabase的setFallbackFamily来针对中文配置:
// 先拿到文泉驿的字体族名(确保和你查询到的完全一致!) QString zenHeiFamily = "WenQuanYi Zen Hei"; // 为简体中文的Unicode范围指定fallback字体 QFontDatabase::setFallbackFamily(QFontDatabase::SimplifiedChinese, zenHeiFamily);
之后再设置Open Sans为全局字体,这样只要碰到Open Sans不支持的中文字符,就会触发这个全局fallback规则,自动用文泉驿渲染。
方法三:排查字体文件本身的问题
有时候可能是你用的Open Sans字体文件没有正确声明它不支持的字符范围,导致Qt不知道需要fallback。你可以用代码验证一下:
QFontDatabase db; // 检查Open Sans能不能渲染"中"这个字 bool supportsChinese = db.hasCharacter("Open Sans", QChar('中')); qDebug() << "Open Sans 支持中文吗?" << supportsChinese;
如果返回false,那确实是字体本身不支持中文,这时候用前面两种方法就能解决。
最后提个小细节:一定要确保代码里用的字体族名和你查询QFontDatabase得到的完全一致,比如"Open Sans"不能写成"OpenSans",大小写或者空格错了,Qt都会找不到字体哦!
内容的提问来源于stack exchange,提问作者RadioRaheem

