How to change image of win btn in same position

Newbie question.


I would like to change de button image of a window, for learning reasons only.

ie: when i press(toggle) the button, the image change from “LV_SYMBOL_POWER” to “LV_SYMBOL_CLOSE”.

If i use a “global/local” variable like “lv_obj_t * win_btn” and i assign “lv_win_add_btn()” function, others buttons are created(added, function name) side by side the original button.

Probably i can only do that with a common button ?!

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


What do you want to achieve?

Change the image of win button after button pressed(button image toggle).

Code to reproduce

 * @file terminal.c

 *      INCLUDES
#include "terminal.h"


 *      DEFINES
#define TERMINAL_ANIM_TIME   100 /*[ms]*/
#define TERMINAL_NO_INPUT    0   /*Do not create Text area and Keyboard*/
#define TERMINAL_LOG_LENGTH  512        /*Characters*/

 *      TYPEDEFS

static void clr_event_cb(lv_obj_t * btn, lv_event_t event);
static void win_close_action(lv_obj_t * btn, lv_event_t event);

static lv_obj_t * win;
static char txt_log[TERMINAL_LOG_LENGTH + 1];
static lv_obj_t * label;
static lv_obj_t * clr_btn;

static lv_obj_t * win_btn;

 *      MACROS


 * Open a terminal
 * @return pointer to the terminal window
lv_obj_t * terminal_create(void)
    static lv_style_t style_bg;
    lv_style_copy(&style_bg, &lv_style_pretty);
    style_bg.body.main_color = lv_color_make(0x30, 0x30, 0x30);
    style_bg.body.grad_color = lv_color_make(0x30, 0x30, 0x30);
    style_bg.body.border.color = LV_COLOR_WHITE;
    style_bg.text.color = lv_color_make(0xE0, 0xE0, 0xE0);

    lv_coord_t hres = lv_disp_get_hor_res(NULL);
    lv_coord_t vres = lv_disp_get_ver_res(NULL);

    **win = lv_win_create(lv_disp_get_scr_act(NULL), NULL);**
**    lv_win_set_style(win, LV_WIN_STYLE_BG, &style_bg);**
**    lv_obj_set_size(win, hres, vres);**
**    lv_win_set_sb_mode(win, LV_SB_MODE_AUTO);**
**    lv_win_set_title(win, "Xunda");**
**    //lv_obj_t * **
**    win_btn = lv_win_add_btn(win, LV_SYMBOL_POWER);    // LV_SYMBOL_CLOSE**
**    lv_obj_set_event_cb(win_btn, win_close_action);**

**    /*Make the window's content responsive*/**
**    lv_win_set_layout(win, LV_LAYOUT_PRETTY);**

    /*Create a label for the text of the terminal*/
    label = lv_label_create(win, NULL);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, lv_win_get_width(win));
    lv_label_set_static_text(label, txt_log);               /*Use the text array directly*/

    /*Create a clear button*/
    clr_btn = lv_btn_create(win, NULL);
    lv_btn_set_fit(clr_btn, LV_FIT_TIGHT);
    lv_obj_set_event_cb(clr_btn, clr_event_cb);
    lv_obj_t * btn_label = lv_label_create(clr_btn, NULL);
    lv_label_set_text(btn_label, "Clear");

    return win;

 * Add data to the terminal
 * @param txt_in character sting to add to the terminal
void terminal_add(const char * txt_in)
    if(win == NULL) return;                 /*Check if the window is exists*/

    uint16_t txt_len = strlen(txt_in);
    uint16_t old_len = strlen(txt_log);

    /*If the data is longer then the terminal ax size show the last part of data*/
    if(txt_len > TERMINAL_LOG_LENGTH) {
        txt_in += (txt_len - TERMINAL_LOG_LENGTH);
        txt_len = TERMINAL_LOG_LENGTH;
        old_len = 0;
    /*If the text become too long 'forget' the oldest lines*/
    else if(old_len + txt_len > TERMINAL_LOG_LENGTH) {
        uint16_t new_start;
        for(new_start = 0; new_start < old_len; new_start++) {
            if(txt_log[new_start] == '\n') {
                /*If there is enough space break*/
                if(new_start >= txt_len) {
                    /*Ignore line breaks*/
                    while(txt_log[new_start] == '\n' || txt_log[new_start] == '\r') new_start++;

        /* If it wasn't able to make enough space on line breaks
         * simply forget the oldest characters*/
        if(new_start == old_len) {
            new_start = old_len - (TERMINAL_LOG_LENGTH - txt_len);
        /*Move the remaining text to the beginning*/
        uint16_t j;
        for(j = new_start; j < old_len; j++) {
            txt_log[j - new_start] = txt_log[j];
        old_len = old_len - new_start;
        txt_log[old_len] = '\0';


    memcpy(&txt_log[old_len], txt_in, txt_len);
    txt_log[old_len + txt_len] = '\0';

    lv_label_set_static_text(label, txt_log);
    lv_win_focus(win, clr_btn, TERMINAL_ANIM_TIME);


 * Called when the Clear button is click to clear the text of the terminal
 * @param btn pointer to the clear button
 * @param event the current event
static void clr_event_cb(lv_obj_t * btn, lv_event_t event)
    (void) btn;    /*Unused*/

    if(event != LV_EVENT_CLICKED) return;

    txt_log[0] = '\0';
    lv_label_set_static_text(label, txt_log);   /*Refresh the text*/

 * Called when the window's close button is clicked
 * @param btn pointer to the close button
 * @return LV_ACTION_RES_INV because the button is deleted in the function
static void win_close_action(lv_obj_t * btn, lv_event_t event)
    (void) btn;    /*Unused*/

    if(event != LV_EVENT_CLICKED) return;

    //win = NULL;

    static bool f = 0;
    f = !f;

       win_btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE);
       win_btn = lv_win_add_btn(win, LV_SYMBOL_POWER);

#endif /*LV_USE_TERMINAL*/

Screenshot and/or video

Enjoying the question,

How to alter the thickness size of “title bar” in a “win” object ?

How to alter the “button” size inside “titlebar” of “win” object ?


I suggest that you read the documentation for the window object.

  1. lv_win_add_btn returns a pointer to the created button. The created button contains an lv_img object as its first child. You can then change the source of that lv_img object with lv_img_set_src.
  2. The easiest way to change the height is probably to alter the padding in the window’s header style.
  3. You can modify the size of the control buttons with the lv_win_set_btn_size(win, new_size) function.

Note that changing the size of the control buttons changes all of them. If you want to change one button setting its size manually is probably easier.