Qt QML 中为 CheckBox 设置鸿蒙字体(HarmonyOS Sans)——适配 Qt 5.6.x 与 Qt 5.12+

📖 目录

一、鸿蒙字体简介

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

三、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 自定义文本(推荐)

通过 CheckBoxStylelabel 属性自定义文本控件,完全控制字体样式,同时保留 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"
            }
        }
    }
}
}
关键说明
  • controlCheckBoxStyle 内部指向外层的 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.cppqDebug() 输出的实际族名,如 "HarmonyOS Sans SC",然后在 QML 中严格使用该名称。

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

原因 :忘记在 labelText 中设置 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 生态保持一致!

相关推荐
赏金术士18 分钟前
Kotlin 从入门到进阶 之协程 Flow 模块(九)
开发语言·kotlin·php
赵钰老师19 分钟前
R语言在生态环境领域中的应用
开发语言·数据分析·r语言
guygg8822 分钟前
四旋翼无人机串级PID控制MATLAB仿真
开发语言·matlab·无人机
guygg8824 分钟前
四足液压机器人设计程序MATLAB实现
开发语言·matlab·机器人
轻口味26 分钟前
HarmonyOS 6.1 全栈实战录 - 04 镜像世界:Spatial Recon Kit 3D空间重建与企业级高精度建模实战
3d·华为·harmonyos
Frank_refuel33 分钟前
C++之STL->string类的使用和实现
java·开发语言·c++
feifeigo12335 分钟前
图像重建中软阈值方法的原理和MATLAB实现
开发语言·matlab
江南十四行36 分钟前
Python多线程与多进程实战——避开GIL,榨干CPU
开发语言·网络·python
88号技师38 分钟前
2026年2月新锐一区SCI-完整家庭互动优化算法Undivided Family Interaction Algorithm-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法
手揽回忆怎么睡42 分钟前
java打包无效的发行版:xx,临时修复当前窗口指定 JDK21
java·开发语言