LVGL使用i18n库配置多语言的方法

项目需要一个切换显示语言的功能,发现LVGL官方已经提供了,但是没有例程,于是自学了一下。

以下内容根据lv_i18n官方readme GitHub - lvgl/lv_i18n: Internationalization (i18n) for LVGL

第0步:配置环境

因为lv_i18n库基于一个js脚本,所以我们要先安装好node.js环境。然后在命令行输入

npm i lv_i18n -g

官方还提供了其他两种安装方法,我只用了第一种,所以不再赘述。

第1步:准备词条文件

1. 准备好你的词条、语言代码和别名,默默的记在心里或者写在本子上

  • 词条就是你想让它显示的东西,比如"Hello World!"。
  • 语言代码就是这个词条的语言,比如英语-大不列颠就是en-GB。这里要注意,语言代码必须符合i18n规范,也就是“语言-地区”的格式,具体可以到ISO language codes | Andiamo! The Language Professionals 查阅对应的语言代码。
  • 别名类似变量名,就是这个词条的名字,比如"hello"。

2.  在项目文件夹内为每一种语言创建词条文件,比如我有两种语言en-GB和de,那么我创建了en-GB.yml和de.yml。(理论上可以把多种语言合并到同一文件,但是我没有试过)

3. 其实官方提供了一个extract命令创建示例,但是我们可以跳过,直接上手编写文件。我的文件是这样的:

en-GB:
  title1: Main menu
  title2: Sub menu
  user_logged_in:
    one: One user is logged in
    other: '%d users are logged in'

下面分别按照每一级讲解

  • 第一级:语言代码
  • 第二级:词条别名和词条
  • 第三级:内置的关键字,目前只能使用one和other,作用是根据另一个变量实时更改显示的字段,这个后面在代码会使用到

如法炮制编写de.yml

de:
  title1: Hauptmenü
  title2: Untermenü
  user_logged_in:
    one: Ein Benutzer ist angemeldet
    other: '%d benutzer ist angemeldet'

第3步:编译成c文件

在命令行运行(注意路径)

lv_i18n compile -t 'translations/*.yml' -o 'src/lv_i18n'

会生成lv_i18n.c和lv_i18n.h文件,将它添加进你的项目里就可以使用了。

其中词条是以结构体数组的形式存储在c里的,就像

static lv_i18n_phrase_t de_plurals_one[] = {
    {"user_logged_in", "Ein Benutzer ist angemeldet"},
    {NULL, NULL} // End mark
};

可以自己研究

第4步:在自己的项目里使用

1. 初始化

lv_i18n_init(lv_i18n_language_pack);

2. 选择语言(默认是en-GB)

lv_i18n_set_locale("en-GB");

3. 显示字符有两种方法,对应有两个宏,分别是"_"和"_p",这两个宏定义在lv_i18n.h里

#define _(text) lv_i18n_get_text(text)
#define _p(text, num) lv_i18n_get_text_plural(text, num)

_就是普通的按照别名查找词条字符串:

lv_label_set_text(label1, _("title1"));

_p有两个输入,一个是词条,一个是数字,这个数字的用法是,当num=1时,输出词条one,当num!=1时,输出词条other。例子在这:

sprintf(buf, _p("user_logged_in", user_cnt)), user_cnt);  

一切以官方教程为准

GitHub - lvgl/lv_i18n: Internationalization (i18n) for LVGL

<think>嗯,用户想了解在ESP32-S3 IDF 5.4版本和LVGL 9.2.0中如何支持多国语言,特别是中文和英文。首先,我需要确认ESP-IDF和LVGL的版本兼容性。IDF 5.4应该没问题,但LVGL 9.2.0可能有一些API变化,需要查文档。 接下来,多语言支持通常涉及国际化(i18n)机制。LVGL本身有没有内置的多语言支持呢?记得在之前的版本中,可能需要自己实现或者用第三方。比如使用gettext或者类似的字符串替换方法。不过用户可能希望用LVGL原生的方式。 然后,中文显示需要字体支持。用户需要包含中文字体文件,比如使用LVGL的字体转换工具生成C数组或者bin文件。ESP32-S3的存储空间是否足够?可能需要外部Flash或者分区调整。另外,字体子系统的设置是否正确,比如启用UTF-8编码。 还有,语言切换的逻辑。如何在运行时动态切换语言?可能需要维护一个字符串表,根据当前语言选择对应的字符串。LVGL的标签控件如何更新文本?可能需要手动刷新或者触发事件。 另外,考虑存储多国语言的字符串,可能用结构体数组或者哈希表,每个键对应不同语言的字符串。比如一个二维数组,第一维是语言,第二维是字符串ID。 然后,步骤分解。首先准备中英文的字体,然后在LVGL配置,接着处理字符串的存储和切换,最后在UI控件上应用。可能还需要示例代码片段,帮助用户理解实现。 还要注意内存管理,尤其是中文字体可能较大,是否启用压缩或者分区存储。IDF中的分区表配置可能需要调整,确保字体文件存储在合适的分区,比如SPIFFS或者LittleFS。 另外,检查LVGL的文档,看是否有语言包的支持或者相关的示例。可能在社区或者官方论坛有类似的实现案例,可以借鉴。 最后,测试环节。用户需要验证中英文切换是否正常,显示是否正确,是否有乱码或者内存溢出问题。可能需要调试字体加载和渲染过程。</think>在 ESP32-S3 (IDF 5.4) 和 LVGL 9.2.0 中实现多国语言支持(中英文),可通过以下结构化步骤实现: $$ \text{实现流程} = \text{字体准备} + \text{字符串管理} + \text{动态切换逻辑} $$ --- ### 一、字体准备(中文/英文显示基础) 1. **生成字体文件** 使用 LVGL 官方工具 [LVGL Font Converter](https://lvgl.io/tools/fontconverter): - 选择中英文字符集(如 GB2312 或 Unicode) - 输出格式选择 `Bin` 或 `C array` - 示例:`arial_40_chs_en.bin` 包含中文+英文字形 2. **存储字体文件** 将生成的字体文件存入 ESP32 分区: ```c // partitions.csv 新增配置 otadata, data, ota, 0x10000, 0x2000 nvs, data, nvs, 0x12000, 0x6000 fonts, data, fat, 0x18000, 0x100000 // 字体存储分区 ``` 3. **注册字体** 在代码中初始化字体: ```c lv_font_t * font_chs_en = lv_font_load("F:/fonts/arial_40_chs_en.bin"); lv_style_set_text_font(&style_default, font_chs_en); ``` --- ### 二、多语言字符串管理 1. **创建语言映射表** 使用结构体数组定义键值对: ```c typedef struct { const char* key; const char* en; const char* zh; } lang_entry_t; static const lang_entry_t lang_table[] = { {"welcome", "Welcome", "欢迎"}, {"settings", "Settings", "设置"}, // ... 其他条目 }; ``` 2. **实现翻译函数** 动态获取当前语言字符串: ```c const char* tr(const char* key) { static uint8_t lang = LANG_EN; // 当前语言状态 for(int i=0; i<sizeof(lang_table)/sizeof(lang_entry_t); i++) { if(strcmp(key, lang_table[i].key) == 0) { return (lang == LANG_EN) ? lang_table[i].en : lang_table[i].zh; } } return key; // 未找到时返回键名 } ``` --- ### 三、动态语言切换实现 1. **语言状态存储** 使用非易失存储 (NVS) 保存用户选择: ```c nvs_handle_t nvs; nvs_open("lang_store", NVS_READWRITE, &nvs); nvs_set_u8(nvs, "lang", target_lang); // 保存语言选项 nvs_commit(nvs); ``` 2. **UI 刷新机制** 语言切换时遍历更新所有控件: ```c void update_all_labels(lv_obj_t* parent) { for(int i=0; i<lv_obj_get_child_cnt(parent); i++) { lv_obj_t* child = lv_obj_get_child(parent, i); if(lv_obj_check_type(child, &lv_label_class)) { const char* key = lv_label_get_text(child); lv_label_set_text(child, tr(key)); } } } ``` --- ### 四、关键注意事项 1. **内存优化** 使用 LVGL 的字体压缩特性: ```c lv_font_set_compress(font_chs_en, true); ``` 2. **编码一致性** 确保所有源文件使用 UTF-8 编码: ```makefile # CMakeLists.txt 添加 add_compile_options(-exec-charset=UTF-8 -input-charset=UTF-8) ``` 3. **触控反馈** 添加语言切换按钮交互: ```c lv_obj_add_event_cb(btn_switch, switch_lang_handler, LV_EVENT_CLICKED, NULL); ``` --- ### 五、验证步骤 1. 编译时检查字体是否被正确链接 2. 通过串口监控内存使用量(确保未溢出) 3. 测试极端字符(如中英文混合字符串 "Hello 世界!") 完整示例代码可参考 ESP-IDF 官方示例仓的 `lvgl_i18n` 案例。实际开发中建议使用 gettext 标准化方案提升可维护性。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kur1k0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值