MaixCDK 国际化(i18n)与多语言支持
你可以使用任何喜欢的国际化库,例如 gettext,它支持 Python 和 C++。
此外,我们还提供了一个简单的 i18n 库,适用于简单的使用场景。
针对 MaixPy
请参阅 MaixPy 国际化文档。
针对 MaixCDK
与 MaixPy 相同,有两种方法可以使用:
简单的翻译字典
首先确保你的源文件编码为 UTF-8
。
#include "maix_i18n.hpp"
const std::map<string, string> locale_zh_dict = {
{"out", "输出"},
{"hello", "你好"}
};
const std::map<string, string> locale_ja_dict = {
// {"out", "出力"},
{"hello", "こんにちは"}
};
const std::map<string, const std::map<string, string>> locales_dict = {
{"zh", locale_zh_dict},
{"ja", locale_ja_dict}
};
i18n::Trans trans(locales_dict);
int main()
{
log::info("系统语言: %s\n", i18n::get_locale().c_str());
log::info("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
trans.set_locale("zh");
printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
trans.set_locale("en");
printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
trans.set_locale("ja");
printf("%s: %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
return 0;
}
分离的翻译文件
上面的示例适用于少量翻译字符串。如果需要翻译大量字符串,推荐使用此方法:
- 不需要修改源代码即可更换翻译内容,翻译字符串保存在独立的 yaml 文件中。
- 更容易定位翻译字符串,支持自动扫描需要翻译的字符串,并自动生成 yaml 文件。
err::Err e = trans.load("locales"); // 从 locales 目录加载翻译文件
err::check_raise(e, "加载翻译 yaml 文件失败");
log::info("系统语言: %s\n", i18n::get_locale().c_str());
log::info("%s: %s, %s\n", i18n::get_locale().c_str(), trans.tr("out").c_str(), trans.tr("hello").c_str());
trans.set_locale("zh");
log::info("zh: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
trans.set_locale("en");
log::info("en: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
trans.set_locale("ja");
log::info("ja: %s, %s\n", trans.tr("out").c_str(), trans.tr("hello").c_str());
完整示例请参见 examples/i18n。
然后执行 maixtool i18n -d . r
,这将扫描所有使用 tr()
或 _()
的翻译字符串,生成 locales
目录和翻译文件。手动翻译 locales
中的 yaml 文件后,将其放置在程序旁边并运行。
在 LVGL 应用中显示国际化字体
查看如何显示自定义字体:https://neucrack.com/p/514。
使用以下代码:
LV_FONT_DECLARE(zh_fonts);
static const std::map<string, void*> fonts = {
{"zh", (void*)&zh_fonts}
};
const lv_font_t *get_font_by_locale(const string &locale)
{
const std::map<string, void*>::const_iterator iter = fonts.find(locale);
if (iter == fonts.end())
{
return &zh_fonts;
}
return (lv_font_t *)iter->second;
}
最后,使用国际化字体:
std::string locale = i18n::get_locale();
lv_obj_set_style_text_font(lv_scr_act(), get_font_by_locale(locale), LV_PART_MAIN);
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, trans.tr("hello").c_str());