You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:07:17