I need an example for lv_i18n

Important: posts that do not use this template will be ignored or closed.

Before posting

  • Get familiar with Markdown to format and structure your post
  • Be sure to update lvgl from the latest version from the master branch.
  • Be sure you have checked the relevant part of the documentation. We will not respond in detail to posts where you haven’t read the relevant documentation.
  • If applicable use the Simulator to eliminate hardware related issues.

Delete this section if you read and applied the mentioned points.


Hello guys,
I need an example of language translation. I have done fallowing example from https://github.com/lvgl/lv_i18n but it did not work on simulator.

What MCU/Processor/Board and compiler are you using?

What do you want to achieve?

I have created .c and .h files using ```c lv_i18n compile -t ‘translations/*.yml’ -o 'lv_i18n ``

What have you tried so far?

https://github.com/lvgl/lv_i18n#mark-up-the-text-in-your-code added to my file but getting errors for lv_i18n_language_pack.

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

/*You code here*/
/*this code is inside main block*/
/* en-GB.yml file
  title1: Main menu
  pedal_warning: Please plug pedal
    one: One user is logged in
    other: '%d users are logged in'
    lv_obj_t * scr = lv_disp_get_scr_act(NULL);     /*Get the current screen*/

    // /*Create a Label on the currently active screen*/

    lv_obj_t * label =  lv_label_create(scr, NULL);
    lv_label_set_text(label, _("title1"))

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

Does it help if you include lv_i18n.h?

No, it does not.

What error do you get exactly?

They are already define in lv_i18n, and i have also tried to extern language_pack. I am using lvgl_version 6.0.0

It doesn’t look like the generated C file is in the Makefile’s source file list.

1 Like

I am checking it.

It worked thanks. I will share solution.

This solution works for simulator:
1- Create *.mk file in lv_i18n folder, so mine is lv_i18n.mk
add lines below to *.mk file you have created (lv_i18n.mk)

CSRCS += lv_i18n.c
DEPPATH += --dep-path $(LVGL_DIR)/lv_i18n
VPATH += :$(LVGL_DIR)/lv_i18n
CFLAGS += "-I$(LVGL_DIR)/lv_i18n"

2- Add include $(LVGL_DIR)/lv_i18n/lv_i18n.mk into Makefile

3- Update file to show lv_i18n header and C files in CMakeList.txt, so mine is look like:

file(GLOB_RECURSE INCLUDES "lv_drivers/*.h" "lv_examples/*.h"   "lvgl/*.h"    "lv_i18n/*.h"  "./*.h" )
file(GLOB_RECURSE SOURCES  "lv_drivers/*.c" "lv_examples/*.c"   "lv_i18n/*.c"  "lvgl/*.c" )

It looks like working but when i switch language it is not changing on label, so do i miss something to do it? Do i need to call it again?

it prints outs title when i switch language but not changed in label

I think you may have to set the label’s text again. I don’t think there is any hook that changes it automatically.

OK. Thanks, i will create task to refresh when i switch language.

Yes, the label’s text needs to set again.

In V5, there was LV_SIGNAL_LANG_CHG in the signal.
So the user only needs to call lv_lang_set() to modify the current language.
Why is this feature not supported in the new version?

I have not used language packet in V5 but i wrote function to get message id by message for v6.x. So you can get message id then update text.

  * Get message id by message
const char *ay_i18n_get_message_id(const char * msg) {
  static uint8_t lang_id;
  uint16_t i;

  const char *cur_lang_name = lv_i18n_get_current_locale();

  // update for your languages
  if(strcmp(cur_lang_name,"en-GB")) {
    lang_id = 0; // english
  } else {
    lang_id = 1; // turkish

  // FIXME: update for plurals 
  if(lv_i18n_language_pack[lang_id]->singulars != NULL) {
    lv_i18n_phrase_t * trans = lv_i18n_language_pack[lang_id]->singulars;
    for(i = 0; trans[i].translation != NULL; i++) {
      if(strcmp(trans[i].translation, msg) == 0) {
        /*The msg_id has found. Check the translation*/
        if(trans[i].msg_id) return trans[i].msg_id;
  return NULL;

I didn’t understand your code.

My application is to use the roller to switch to a different language.
I want to refresh the text of all labels of the entire obj tree in the event_cb of the roller.
In v6, I can only update one by one manually, there is no way like lv_lang_set().

You need to call all labels then update text.

* en.yml
* en-GB:
*       warning: "WARNING!"
* tr.yml
* en-GB:
*       warning: "UYARI!"
* Also you need to create lv_i18n.c/h by using 
* lv_i18n compile -t 'translations/*.yml' -o 'lv_i18n'
* in terminal
// I assume that your label already created above
// you need to take lines below to your event  function
const char *text , *text_id;
text = lv_label_get_text(your_label);
// this function from above (i wrote)
text_id = ay_i18n_get_message_id(text);
//this is for update text
lv_label_set_text(your_label, _(text_id));

It will be updated when language is changed

I understand what you mean. This is manually updated one by one.

In V5, after calling lv_lang_set(), these are automatically updated.

Is there any way to automatically update the text of all labels similar to v5’s lv_lang_set() function?

There is no automatic way in the new versions. When the multilanguage support was rewritten we decided to use this method because the “normal” gettext work like this as well.