Qt C++如何获取包含替代字体的全部系统字体列表?
Qt获取系统字体族及替代字体的实现方案
问题背景
需要实现一个下拉框,展示所有系统可用字体族及其替代字体(如Arial Baltic、Arial Greek这类区域变体字体)。尝试通过以下步骤实现但失败:
- 调用
QFontDatabase::families()获取所有系统字体族 - 遍历每个字体族,调用
QFont::substitutes()或QFont::substitutions()获取替代字体 - 结果始终返回空
QStringList,但注册表中存在大量系统字体替代项
原因分析
QFont::substitutes()和QFont::substitutions()仅作用于通过QFont::insertSubstitutions()手动插入的自定义字体替代规则,不会读取系统层面的字体替代配置,因此无法获取系统自带的区域变体字体。
解决方案
1. 跨平台方案(推荐)
使用QFontDatabase的allFonts()方法枚举所有已加载的字体,提取每个字体的显示名称和家族信息:
QFontDatabase db; QList<QFont> allFonts = db.allFonts(); QSet<QString> fontNames; for (const QFont& font : allFonts) { QFontInfo fontInfo(font); // 添加字体显示名(如Arial Baltic) fontNames.insert(fontInfo.family()); } // 将集合转为有序列表用于下拉框 QStringList fontList = fontNames.values(); fontList.sort();
这种方式能跨Windows、Linux、macOS等平台获取所有可见字体,包括区域变体。
2. Windows平台特定方案
若仅需适配Windows,可使用WINAPI的EnumFontFamiliesEx函数枚举所有字体,包括系统注册的替代字体:
#include <windows.h> // 回调函数,处理枚举到的字体 int CALLBACK EnumFontProc(const LOGFONT* lplf, const TEXTMETRIC* lptm, DWORD dwType, LPARAM lpData) { QStringList* fontList = reinterpret_cast<QStringList*>(lpData); QString fontName = QString::fromWCharArray(lplf->lfFaceName); if (!fontList->contains(fontName)) { fontList->append(fontName); } return 1; // 继续枚举 } // 枚举所有系统字体 QStringList getWindowsFonts() { QStringList fontList; HDC hdc = GetDC(nullptr); LOGFONT logFont = {0}; logFont.lfCharSet = DEFAULT_CHARSET; EnumFontFamiliesEx(hdc, &logFont, EnumFontProc, reinterpret_cast<LPARAM>(&fontList), 0); ReleaseDC(nullptr, hdc); fontList.sort(); return fontList; }
此方法能直接获取系统注册表中所有字体项,但代码仅适用于Windows平台。
内容的提问来源于stack exchange,提问作者p.ivanov
相关产品推荐
相关产品推荐

