cool-retro-term字体列表API详解:如何获取和管理所有可用字体
【免费下载链接】cool-retro-termA good looking terminal emulator which mimics the old cathode display...项目地址: https://gitcode.com/GitHub_Trending/co/cool-retro-term
cool-retro-term 是一款复古 CRT 风格的终端模拟器,内置 20 多种怀旧与现代等宽字体。本文详解它的字体列表 API:如何通过FontManager与FontListModel获取、筛选和管理所有可用字体,涵盖内置字体注册表、系统字体扫描、过滤规则与 QML 端调用方式。
字体列表API的两大核心角色
cool-retro-term 的字体体系由两个 C++ 类协作完成,均在 app/main.cpp 中注册为 QML 类型:
| 类 | 职责 | 源码 |
|---|---|---|
FontManager | 收集、筛选、切换字体,发出字体变更信号 | fontmanager.h |
FontListModel | 以 Qt 列表模型形式暴露字体条目,供 QML 下拉框绑定 | fontlistmodel.h |
💡FontListModel被声明为"不可直接创建"——它只能由FontManager内部生成,保证了数据来源的唯一性。
获取全部字体:两个列表属性
FontManager构造时会自动执行两次字体收集(见 fontmanager.cpp):
- 内置字体:通过
populateBundledFonts()从应用资源中注册 Terminus、Hack、JetBrains Mono、Unscii 等 20 多种字体(populateBundledFonts); - 系统字体:
populateSystemFonts()借助QFontDatabase扫描系统已安装字体,并只保留等宽(fixed-pitch)字体,同时跳过与内置字体同名的家族,避免重复(retrieveMonospaceFonts、populateSystemFonts)。
合并后的完整清单通过两个只读属性对外暴露:
fontList:全部字体的原始清单(m_allFonts);filteredFontList:按当前配置过滤后的清单,这是界面实际使用的列表。
每个字体条目的完整字段
一条字体记录FontEntry包含 9 个字段(FontEntry 定义):
| 字段 | 含义 |
|---|---|
name | 内部标识,如TERMINESS_SCALED、HACK |
text | 下拉框中展示的显示名 |
source | 内置字体的资源路径;系统字体为空 |
baseWidth | 基础字宽(低清字体会自动计算修正) |
pixelSize | 原生像素高度,低清字体为 8/11/16,现代字体为 32 |
lowResolutionFont | 是否为需放大的低分辨率像素字体 |
isSystemFont | 是否来自系统 |
family | Qt 实际识别的字族名 |
fallbackName | 字符缺失时的后备字体 |
QML 侧通过模型的角色名(role name)访问这些字段,角色映射见 roleNames()。
获取单个字体详情:get(index) 方法
FontListModel提供了一个便捷的Q_INVOKABLE方法get(index),一次返回指定索引字体的完整属性字典(get() 实现)。它是 QML 里"按下标取一条字体"的标准入口:
var font = appSettings.filteredFontList.get(currentIndex) appSettings.fontName = font.name⚠️ 注意:get()越界时返回空字典而非报错,QML 侧建议先用count属性校验范围。
过滤规则:为什么有时列表里"少了一些"字体
filteredFontList不是简单复制,updateFilteredFonts()(过滤逻辑)按两层条件筛选:
- 来源过滤(
fontSource):0只显示内置字体,1只显示系统字体; - 渲染模式过滤(
rasterization):当渲染模式为"Modern"(值 4)时只显示高分辨率字体,其余模式只显示低清像素字体(系统字体不受此限制)。
🔍 还有一个贴心的细节:过滤后如果当前选中的字体不在新列表里,会自动回退到列表第一项并发出fontNameChanged信号,保证界面永不悬空。
管理字体:属性写入与变更信号
FontManager的全部可写属性都会触发"过滤 + 重算"流水线(以 setFontSource 为例):
| 属性 | 作用 | 范围/示例 |
|---|---|---|
fontSource | 切换内置 / 系统字体 | 0 / 1 |
rasterization | 渲染模式 | Default、Scanlines、Pixels、Sub-Pixels、Modern |
fontName | 指定字体内部名 | TERMINESS_SCALED、HACK… |
fontScaling | 字号缩放(滑块 0.75 起) | 与baseFontScaling相乘生效 |
fontWidth/lineSpacing | 字宽与行距 | 0.5–1.5 / 0.0–1.0 |
字体参数最终经由terminalFontChanged信号下发给终端渲染层(updateComputedFont),PreprocessedTerminal.qml 连接该信号并调用refresh()完成应用。
内置字体速查表
| 内部名 | 显示名 | 类型 |
|---|---|---|
TERMINESS_SCALED | Terminess | 低清(默认) |
UNSCII_8_SCALED/UNSCII_16_SCALED | Unscii 8 / 16 | 低清 |
COMMODORE_64_SCALED | Commodore 64 | 低清 |
IBM_VGA_8x16 | IBM VGA 8x16 | 低清 |
HACK/FIRA_CODE/IOSEVKA | Hack / Fira Code / Iosevka | 现代高分辨率 |
JETBRAINS_MONO | JetBrains Mono | 现代高分辨率 |
OPENDYSLEXIC | OpenDyslexic | 现代(阅读障碍友好) |
完整 20 余条注册见 populateBundledFonts,字体文件位于 app/qml/fonts/。
QML 实战:字体下拉框是怎么接上的
设置面板的"Terminal"页签是字体列表 API 的完整示范(SettingsTerminalTab.qml):
ComboBox的model绑定appSettings.filteredFontList,textRole取"text";- 用户选中时调用
get(currentIndex),并根据lowResolutionFont自动切换渲染模式——选高分字体自动进 Modern 模式,选低清字体自动回到 Default; - 通过
Connections监听onTerminalFontChanged与onFilteredFontListChanged,在字体列表变动时调用updateIndex()同步下拉框选中项。
FontManager在 ApplicationSettings.qml 中创建,并将filteredFontList等属性 alias 给全局appSettings,因此任何 QML 文件都能访问。
总结
- 拿全量字体用
fontManager.fontList,拿界面可见列表用fontManager.filteredFontList; - 按索引取详情用
get(index),返回包含 9 个字段的字典; - 改字体只需写
fontName/fontSource/rasterization属性,过滤与渲染参数重算全自动完成; - 扩展新字体时,在 fontmanager.cpp 中调用
addBundledFont()注册一条FontEntry即可,无需改动其他代码。
掌握这套 API,你就能轻松为 cool-retro-term 定制任何想要的复古字体体验 🖥️
【免费下载链接】cool-retro-termA good looking terminal emulator which mimics the old cathode display...项目地址: https://gitcode.com/GitHub_Trending/co/cool-retro-term
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考