📖 目录

一、鸿蒙字体简介
二、环境准备与字体加载(通用)
三、Qt 5.6.x 版本方案
  3.1 方法一:CheckBoxStyle 自定义文本(推荐)
  3.2 方法二:Row + Text 组合控件(备选)
四、Qt 5.12+ 版本方案
  4.1 方法一:直接使用 font.family(推荐)
  4.2 方法二:全局默认字体统一设置
五、两种版本的核心差异对比
六、常见问题与解决方案
七、总结


一、鸿蒙字体简介

鸿蒙操作系统搭载的 HarmonyOS Sans 是一款无级可变字体,支持中文、英文、数字等多种语言,字形现代、可读性高。在 Qt/QML 应用中使用该字体,可让界面风格与 HarmonyOS 生态保持一致,尤其适合在鸿蒙设备上运行的应用程序。

✅ 核心优势

  • 开源免费,可商用

  • 多字重支持(Regular、Bold、Light 等)

  • 跨平台(Windows、Linux、鸿蒙等均可使用)


二、环境准备与字体加载(通用)

2.1 下载鸿蒙字体

访问华为官方开源社区下载字体包:
https://developer.harmonyos.com/cn/docs/design/font-0000001157868583

将字体文件放入 Qt 项目目录,建议创建 fonts/ 文件夹存放:

  • HarmonyOS_Sans_SC_Regular.ttf(常规字重)

  • HarmonyOS_Sans_SC_Bold.ttf(粗体,可选)

2.2 将字体添加到资源文件(.qrc)

创建或编辑 .qrc 文件(如 resource.qrc):

xml

<RCC>
    <qresource prefix="/fonts">
        <file>fonts/HarmonyOS_Sans_SC_Regular.ttf</file>
        <file>fonts/HarmonyOS_Sans_SC_Bold.ttf</file>
    </qresource>
</RCC>

在 .pro 文件中添加:

makefile

RESOURCES += resource.qrc

2.3 C++ 全局加载字体(推荐,所有版本通用)

在 main.cpp 中通过 QFontDatabase 全局注册字体,一次加载全应用可用:

cpp

#include <QGuiApplication>    // Qt GUI应用程序核心头文件,用于创建GUI应用
#include <QQmlApplicationEngine> // QML引擎头文件,用于加载和运行QML界面
#include <QFontDatabase>      // 字体数据库头文件,用于加载和管理自定义字体
#include <QDebug>             // 调试输出头文件,用于打印日志信息

int main(int argc, char *argv[])
{
    // ===================== 初始化配置 =====================
    // 启用高DPI缩放适配(可选)
    // 作用:提升在高分屏、鸿蒙设备等高清显示设备上的字体/界面显示效果
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    // 创建Qt GUI应用程序对象,管理应用程序的生命周期和事件循环
    QGuiApplication app(argc, argv);

    // ===================== 加载鸿蒙常规字体 =====================
    // 1. 拼接字体文件路径:应用程序运行目录 + fonts文件夹 + 常规字体文件名
    // applicationDirPath():获取当前程序的运行目录(如debug/、release/)
    QString fontPath = QCoreApplication::applicationDirPath() + "/fonts/HarmonyOS_SansSC_Regular.ttf";

    // 2. 加载字体文件到应用程序的字体数据库
    // addApplicationFont():返回字体ID(-1表示加载失败)
    int fontId = QFontDatabase::addApplicationFont(fontPath);

    // 调试输出:打印字体路径,方便排查路径错误
    qWarning() << "fontpath:" << fontPath;

    // 3. 检查字体是否加载成功,并获取字体族名(QML中必须使用该名称)
    if (fontId != -1) {
        // 获取加载成功的字体族名列表(通常只有一个)
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
        // 打印成功日志和字体族名(关键:QML中要严格匹配这个名称)
        qDebug() << "✅ 鸿蒙常规字体加载成功,族名:" << fontFamilies;
        // 输出示例:("HarmonyOS Sans SC")
    } else {
        // 加载失败时打印错误日志,提示检查路径
        qWarning() << "❌ 鸿蒙常规字体加载失败,请检查资源路径!";
    }

    // ===================== 加载鸿蒙粗体字体 =====================
    // 1. 拼接粗体字体文件路径(和常规字体同目录)
    fontPath = QCoreApplication::applicationDirPath() + "/fonts/HarmonyOS_SansSC_Bold.ttf";
    // 2. 加载粗体字体文件
    int boldFontId = QFontDatabase::addApplicationFont(fontPath);

    // 3. 检查粗体字体加载状态
    if (boldFontId == -1) {
        // 粗体加载失败时打印警告(不影响主流程,仅提示)
        qWarning() << "⚠️ 鸿蒙粗体字体加载失败,请检查粗体字体文件路径!";
    } else {
        // 可选:打印粗体字体族名(通常和常规字体族名一致,仅字重不同)
        QStringList boldFontFamilies = QFontDatabase::applicationFontFamilies(boldFontId);
        qDebug() << "✅ 鸿蒙粗体字体加载成功,族名:" << boldFontFamilies;
    }

    // ===================== 加载QML界面 =====================
    // 创建QML引擎对象
    QQmlApplicationEngine engine;
    // 加载主QML文件(资源路径方式,确保打包后能正常访问)
   // engine.load(QUrl(QStringLiteral("qrc:/ck.qml")));

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    // ===================== 启动应用事件循环 =====================
    // 进入应用程序的主事件循环,处理用户交互、界面刷新等事件
    // 没有这一行,程序会加载完成后直接退出
    return app.exec();
}

关键点qDebug() 输出的字体族名(如 HarmonyOS Sans SC)必须在 QML 中严格匹配。


三、Qt 5.6.x 版本方案

版本特征:CheckBox 来自 QtQuick.Controls 1.4,直接设置 font.family 可能无效,需通过自定义样式或组合控件实现。

3.1 方法一:使用 CheckBoxStyle 自定义文本(推荐)

通过 CheckBoxStyle 的 label 属性自定义文本控件,完全控制字体样式,同时保留 CheckBox 的交互功能。

完整代码示例

qml

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4          // 关键:CheckBoxStyle 需要此导入
import QtQuick.Layouts 1.3


Window {
    visible: true
    width: 500
    height: 400
    title: "鸿蒙字体 vs 宋体 对比测试"

    CheckBox {
        id:ck1
        x:100
        y:100

        text: "记住我"                      // 清空默认文本,避免重复显示
        checked: true
    }

CheckBox {
    x:100
    y:200
    id: rememberCheckbox
    text: ""                      // 清空默认文本,避免重复显示
    checked: true                 // 默认选中

    // 自定义样式
     style: CheckBoxStyle {
        // 自定义标签(文本)
        label: Text {
            text: "记住密码"
            font.family: "HarmonyOS Sans SC"   // 鸿蒙字体(与C++输出一致)
            font.pixelSize: 14                 // 字体大小
            color: control.enabled ? (control.checked ? "#333333" : "#999999") : "#CCCCCC"
            verticalAlignment: Text.AlignVCenter
        }

        // 可选:自定义指示器样式
        indicator: Rectangle {
            implicitWidth: 16
            implicitHeight: 16
            radius: 2
            color: control.checked ? "#007AFF" : "white"
            border.color: control.checked ? "#007AFF" : "#CCCCCC"

            // 勾选标记
            Rectangle {
                visible: control.checked
                width: 8
                height: 4
                anchors.centerIn: parent
                rotation: -45
                color: "white"
            }
        }
    }
}
}

关键说明
  • control 在 CheckBoxStyle 内部指向外层的 CheckBox 对象,用于访问 checkedenabled 等状态。

  • 必须将 text 设为空字符串,否则默认文本会与自定义文本重叠。

  • 如果不需自定义指示器,可省略 indicator 块,使用系统默认样式。

3.2 方法二:Row + Text 组合控件(备选)

将 CheckBox 与独立 Text 组合,手动处理点击同步,适用于快速原型。

qml


import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
Row {
        anchors.top: parent.top
        anchors.topMargin: 300
        anchors.left: parent.left
        anchors.leftMargin: 50
        spacing: 8

        CheckBox {
            id: rememberCheckbox1
            text: "记住密码-宋体"           // 清空默认文本
            checked: true
        }


        CheckBox {

            id: rememberCheckbox
            text: ""           // 清空默认文本
            checked: true
        }

        Text {
            text: "记住密码-鸿蒙"

            font.family: "HarmonyOS Sans SC"
            font.pixelSize: 14
            color: rememberCheckbox.enabled ? (rememberCheckbox.checked ? "#333333" : "#999999") : "#CCCCCC"

            // 点击文本时切换复选框状态
            MouseArea {
                anchors.fill: parent
                onClicked: rememberCheckbox.checked = !rememberCheckbox.checked
                cursorShape: Qt.PointingHandCursor
            }
        }
    }

四、Qt 5.12+ 版本方案

版本特征:CheckBox 来自 QtQuick.Controls 2.x(或更高),对 font 属性支持完善,可直接设置,也可通过全局样式统一配置。

4.1 方法一:直接使用 font.family(推荐)

最简单直接的方式,在 CheckBox 上直接设置 font.family 即可生效。

qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 400
    height: 200
    title: "Qt 5.12+ CheckBox 鸿蒙字体"

    CheckBox {
        anchors.centerIn: parent
        text: "记住密码"
        font.family: "HarmonyOS Sans SC"
        font.pixelSize: 14
        checked: true
    }
}

4.2 方法二:全局默认字体统一设置

如果整个应用都希望使用鸿蒙字体,可以在根组件(如 ApplicationWindow)或通过 C++ 设置全局默认字体,所有控件自动继承。

4.2.1 在 ApplicationWindow 中设置

qml

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    visible: true
    width: 400
    height: 200
    title: "全局鸿蒙字体"
    
    // 设置全局默认字体
    font.family: "HarmonyOS Sans SC"
    font.pixelSize: 14

    Column {
        anchors.centerIn: parent
        spacing: 10
        
        CheckBox {
            text: "记住密码"        // 自动继承全局字体
        }
        
        Text {
            text: "其他文本也自动生效"
        }
    }
}
4.2.2 在 C++ 中设置全局默认字体(影响所有 QML)

cpp

// main.cpp
#include <QFont>
// ... 在 main 函数中
QFont defaultFont = app.font();
defaultFont.setFamily("HarmonyOS Sans SC");
defaultFont.setPointSize(14);
app.setFont(defaultFont);

五、两种版本的核心差异对比

对比项 Qt 5.6.x(Controls 1.4) Qt 5.12+(Controls 2.x)
CheckBox 所在模块 QtQuick.Controls 1.4 QtQuick.Controls 2.12
直接设置 font.family 通常无效,需自定义 ✅ 直接有效
推荐方案 CheckBoxStyle 自定义 直接 font.family 或全局字体
备选方案 Row + Text 组合 ApplicationWindow 全局设置
样式模块 需要 import QtQuick.Controls.Styles 1.4 无需额外样式模块
代码简洁度 较复杂 简洁直观

六、常见问题与解决方案

Q1:字体加载后 QML 中显示为默认字体?

原因:C++ 加载的字体族名与 QML 中使用的名称不匹配。
解决:查看 main.cpp 中 qDebug() 输出的实际族名,如 "HarmonyOS Sans SC",然后在 QML 中严格使用该名称。

Q2:Qt 5.6.x 中使用 CheckBoxStyle 后,文本不显示?

原因:忘记在 label 的 Text 中设置 text 属性,或者未清空 CheckBox 的 text 属性。
解决:在 label 中明确设置 text,并将 CheckBox 的 text 设为空字符串。

Q3:Qt 5.12+ 中直接设置 font.family 无效?

原因:可能未正确加载字体,或使用的字体族名错误。
解决:确认 C++ 中加载成功并打印族名,检查 QML 中的字符串是否完全一致。

Q4:两种版本能否混用同一套代码?

不建议。因为 Qt 5.6.x 和 5.12+ 的 CheckBox 类型不同,style 属性在 Controls 2 中已移除。建议通过条件编译或分别维护。

Q5:打包发布后字体丢失?

原因:字体资源未正确包含在可执行文件目录或安装包中。
解决:确保字体文件已通过 .qrc 编译进程序,或在发布时随应用一同复制字体文件,并使用绝对路径加载。


七、总结

✨ 核心要点

  • 字体加载:统一使用 C++ 全局加载(QFontDatabase::addApplicationFont),获取准确族名。

  • Qt 5.6.x:使用 CheckBoxStyle 自定义 label,完全控制字体样式。

  • Qt 5.12+:直接设置 font.family,或通过全局字体统一配置。

🎯 最佳实践建议

  1. 开发前确认 Qt 版本,选择对应方案。

  2. 优先使用 C++ 加载字体,避免 QML 异步加载导致的闪烁。

  3. 调试验证:在 main.cpp 中打印字体族名,在 QML 中使用 console.log 验证控件状态。

  4. 发布前检查:确保字体资源打包正确,避免运行时缺失。

按照本教程操作,你可以在不同 Qt 版本中为 CheckBox 完美集成鸿蒙字体,让界面风格与 HarmonyOS 生态保持一致!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐