LittleVGL

1. Video quick start 

Quick Start LVGL (based on STM32, LVGL 8.2.0)_mucherry's blog-CSDN blog_lvgl

Ten minutes to learn how to use lvgl designer gui guider and simulator to write a simple calculator application_哔哩哔哩_bilibili

SquareLine Studio

STM32 porting LVGL8.0.2 ultra-detailed nanny-level tutorial with ported project files

Chart - 5" Taurus Development Board

Tips: Hold down Ctrl to quickly rename together

2. Transplant LVGL to Puzhong development board

During the transplantation process, follow the video transplantation in 1, but failed to display the demo. It is suspected that disp_flush needs to call the underlying lcd operation interface, which is not the same as the function called in the video. Search and analyze again.

typedef union {
    struct {
        uint16_t blue  : 5;
        uint16_t green : 6;
        uint16_t red   : 5;
    } ch;
    uint16_t full;
} lv_color16_t;
typedef lv_color16_t lv_color_t;

Reference article: https://www.eefocus.com/article/484678.html

 EmbedSummary: Embedded hodgepodge resource summary

Data:22.12.25

LVGL study notes: NXP gui guider+Platformio+ESP32 example-哔哩哔哩

LVGL study notes_William_Zhang_csdn's Blog-CSDN Blog_lvgl

3. lvgl porting punctual atomic video

Codeblocks Shortcut | Ctrl

Lecture 7 Basics - LVGL Transplantation (No Operating System 4)_哔哩哔哩_bilibili

LVGL 8.2 menu-pudn.com

Free Icons, Clipart Illustrations, Photos, and Music

LVGL+SMT32 project exercises (multiple pictures) - Personal Station

4. API functions

The lv_event_t * e parameter of the event callback function 

Get the triggered event code: lv_event_code_t code = lv_event_get_code(e);

Get the object that triggered the event: lv_obj_t * target = lv_event_get_target(e);

Set background color: lv_obj_set_style_bg_color( label, lv_color_hex(0xffe1d4), LV_STATE_DEFAULT );

Set font size: lv_obj_set_style_text_font( label, &lv_font_montserrat_30, LV_STATE_DEFAULT );
 Set text color: lv_obj_set_style_text_color( label, lv_color_hex(0xf7b37b), LV_STATE_DEFAULT );

Turn on the recoloring function: lv_label_set_recolor( label, true );

 Set the color separately: lv_label_set_text( label, "hallo #ff0000 lvgl# " );

Set long text mode: lv_label_set_long_mode(label, LV_LABEL_LONG_...);

 Enable state switching: lv_obj_add_flag( btn, LV_OBJ_FLAG_CHECKABLE ); 

Add state: open by default and cannot be modified: lv_obj_add_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED);

Clear the state of the switch: lv_obj_clear_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED);   

Obtain (judgment) switch state: lv_obj_has_state(switch1, LV_STATE_CHECKED) /* return value: 1, selected; 0, not selected*/

Set the spacing between the text and the check box: lv_obj_set_style_pad_column( checkbox, 20, LV_STATE_DEFAULT );

checkbox and btn use LV_EVENT_VALUE_CHANGED

You can set the state of the application, the part of the application

------------------------------------------------------label--------------------------------------------------------- 

Set the text directly: lv_label_set_text( label, "hallo \n lvgl");
the text is not stored in the dynamic memory, but in the specified buffer (use with caution): lv_label_set_text_static( label, "hallo" );
format the text, Similar to printf: lv_label_set_text_fmt( label, “Value: %d”, 50 );
background color: lv_obj_set_style_bg_color( label, lv_color_hex(0xffe1d4), LV_STATE_DEFAULT );
font size: lv_obj_set_style_text_font( label, & lv_font_montserrat_30, LV_STATE_DEFAULT );
Text color: lv_obj_set_style_text_color( label , lv_color_hex(0xf7b37b), LV_STATE_DEFAULT );
Enable recoloring function: lv_label_set_recolor( label, true ); 
Set color separately: lv_label_set_text( label, "hallo #ff0000 lvgl# " );
Long text mode: lv_label_set_long_mode(label, LV_LAB EL_LONG_... );


enum {     LV_LABEL_LONG_WRAP, /* default mode, if the component size is fixed, the excess text will be clipped */     LV_LABEL_LONG_DOT, /* replace the last 3 characters in the lower right corner of the label with a dot... */     LV_LABEL_LONG_SCROLL, /* scroll back and forth* /     LV_LABEL_LONG_SCROLL_CIRCULAR, /* circular scrolling */     LV_LABEL_LONG_CLIP, /* directly cut off the text part outside the part */ };





------------------------------------------------------btn---------------------------------------------------------  

 Enable state switching: lv_obj_add_flag( btn, LV_OBJ_FLAG_CHECKABLE );

------------------------------------------------------switch--------------------------------------------------------- 

Add state: open by default and cannot be modified: lv_obj_add_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED);
clear switch state: lv_obj_clear_state(switch1, LV_STATE_CHECKED | LV_STATE_DISABLED);
get (judgment) switch state: lv_obj_has_state(switch1, LV_STATE_CHEC KED) /* return value: bool type, on: 1; off: 0 */

 ------------------------------------------------------checkbox--------------------------------------------------------- 

Set the text content: lv_checkbox_set_text( checkbox, "remember the password" );
Set the spacing between the text and the checkbox: lv_obj_set_style_pad_column( checkbox, 20, LV_STATE_DEFAULT ); Add and clear the checkbox state:
lv_obj_add_state(checkbox, LV_STATE_CHECKED | LV_STATE_ DISABLED); /* Add state: selected by default and cannot be modified*/
lv_obj_clear_state(checkbox, LV_STATE_CHECKED | LV_STATE_DISABLED); /* Clear the state of the checkbox*/
Get (judgment) checkbox state: lv_obj_has_state(checkbox, LV_STATE_CHECKED); /* return Value: 1, selected; 0, not selected */

------------------------------------------------------bar---------------------------------------------------------

Set current value: lv_bar_set_value( bar, 50, LV_ANIM_ON ); /*LV_ANIM_ON : animation on*/
Set range value: lv_bar_set_range( bar, -100, 100 );
Set animation time: lv_obj_set_style_anim_time( bar, 500, LV_STATE_DEFAULT ); /* The animation setting must be placed before the current value setting*/
Set mode: lv_bar_set_mode( bar, LV_BAR_MODE_RANGE );
Set the starting value: lv_bar_set_start_value( bar, -50, LV_ANIM_OFF ); Set the timer lv_timer_create(progress_bar_cb,100,NULL);


enum {     LV_BAR_MODE_NORMAL, /* default mode */     LV_BAR_MODE_SYMMETRICAL, /* draw from zero value to current value (current value can be less than 0) */     LV_BAR_MODE_RANGE /* allow to set start value, but start value must be less than current value*/ } ; Note: In the V8.2 version of LVGL, the default mode also allows setting the starting value, but subsequent versions may be modified.                Animation time refers to the drawing time when the old value is refreshed to the new value, not the time required for the current value to change in reality




------------------------------------------------------spinner---------------------------------------------------------

Body: LV_PART_MAIN
Indicator: LV_PART_INDICATOR
Handle: LV_PART_KNOB
Create loader part: lv_obj_t *spinner = lv_spinner_create( parent, spin_time, arc_length );
Set arc color: lv_obj_set_style_arc_color( spinner, lv_color_hex(0x4a9 f00), LV_PART_MAIN ); 
Set the arc width: lv_obj_set_style_arc_width( spinner, 30, LV_PART_MAIN );    
----------------------------------------- -------------LED------------------------------------ ---------------------  

Create LED parts: lv_obj_t *led = lv_led_create( parent );
set LED color: lv_led_set_color( led, lv_color_hex(0xff0000) );
set LED brightness, range 0~255: lv_led_set_brightness( led, 0 );    
turn on LED (set brightness to 255 ): lv_led_on( led );
Turn off the LED: lv_led_off( led );
Toggle the LED state: lv_led_toggle( led );
Quickly center: lv_obj_center();

------------------------------------------------------list---------------------------------------------------------  

Create list widget: lv_obj_t *list = lv_list_create( parent );
Add list text: lv_list_add_text( list, “Settings” );
Add list button: lv_obj_t *btn= lv_list_add_btn( list, LV_SYMBOL_WIFI, “WLAN”); 
Get list button text: lv_list_get_btn_text( list, list_btn );
Manually update the parameters of the object: lv_obj_update_layout(obj_1);
Add the selected focus state when pressed: lv_obj_add_state(btn, LV_STATE_FOCUS_KEY);

------------------------------------------------------dropdown---------------------------------------------------  

Set options: lv_dropdown_set_options( dd, "a\nb\nc\nd");
Set options (static): lv_dropdown_set_options_static( dd, "a\nb\nc\nd ");
Add options, the index starts from 0: lv_dropdown_add_option( dd , "e", 4); /*Cannot use lv_dropdown_set_options_static*/
Set the current selected item: lv_dropdown_set_selected( dd, 1);
Get index: lv_dropdown_get_selected( dd);
Get option text: lv_dropdown_get_selected_str( dd, buf, sizeof(buf )); char buf[10];
set list expansion direction: lv_dropdown_set_dir(dd, LV_DIR_RIGHT);
set icon: lv_dropdown_set_symbol(dd, LV_SYMBOL_RIGHT);

------------------------------------------------------roller---------------------------------------------------

Set option interval: lv_obj_set_style_text_line_space(roller, 30, LV_STATE_DEFAULT);    
Set option content, scroll mode: lv_roller_set_options(roller, “a\nb\nc\nd”, LV_ROLLER_MODE_NORMAL); /* Normal mode*/Set the currently selected item
: lv_roller_set_selected( roller, 3, LV_ANIM_ON);
Set the number of visible rows: lv_roller_set_visible_row_count(roller, 2);
Get the index: lv_roller_get_selected(roller);    
Get the option text: lv_roller_get_selected_str(roller, buf, sizeof(buf)); char buf[10];

------------------------------------------------------slider--------------------------------------------------- 

 Set current value: lv_slider_set_value(slider, 50, LV_ANIM_OFF);
Set range value: lv_slider_set_range(slider, -100, 100);  
Get current value: lv_slider_get_value(slider);
Mode setting: lv_slider_set_mode(slider, LV_SLIDER_MODE_...); NORMAL , SYMMETRICAL, RANGE
set the left value: lv_slider_set_left_value(slider, 20, LV_ANIM_OFF);
get the left value: lv_slider_get_left_value(slider); 

------------------------------------------------------arc--------------------------------------------------- 

Set the current value (need to be within the range value): lv_arc_set_value(arc, 80);    
set the range value: lv_arc_set_range(arc, 0, 200);  
set the foreground arc angle: lv_arc_set_angles(arc, 135, 270); //here You should set the background arc first, and don’t mix it with setting the current value. It will not change the value, which is to change the style.
Set the background arc angle: lv_arc_set_bg_angles(arc, 135, 45);  
set the rotation angle: lv_arc_set_rotation(arc, 180) ;
Get current value: lv_arc_get_value(arc);
Set mode: lv_arc_set_mode(arc, LV_ARC_MODE_REVERSE);
Draw rate, 90°/sec: lv_arc_set_change_rate(arc, 90);
Set background arc width: lv_obj_set_style_arc_width(arc_1,20,LV_PART_MAIN );
set Foreground arc width: lv_obj_set_style_arc_width(arc_1,20,LV_PART_INDICATOR);
Remove the knob: lv_obj_remove_style(arc_2,NULL,LV_PART_KNOB);
Remove the clickable attribute: lv_obj_clear_flag(arc_2,LV_OBJ_FLAG_CLICKABLE);

------------------------------------------------------line--------------------------------------------------- 

Set line coordinate points: static lv_point_t line_points[] = { {15, 5}, {25, 20}, {5, 20}, {15, 5} }; lv_line_set_points(line, line_points, 4); set width
:    
lv_obj_set_style_line_width (line, 8, LV_PART_MAIN); 
Set rounded corners: lv_obj_set_style_line_rounded(line, true, LV_PART_MAIN);
Set y-axis inversion: lv_line_set_y_invert(line, true);

------------------------------------------------------img--------------------------------------------------- 

Declare image: LV_IMG_DECLARE(img_bird);
Set image source: lv_img_set_src(img, &img_bird); // Declare image first before
setting image offset: lv_img_set_offset_x(img, 100);
           lv_img_set_offset_y(img, 20); 
Image recoloring: lv_obj_set_style_img_recolor(img, lv_color_hex(0xffe1d2), LV_PART_MAIN); 
           lv_obj_set_style_img_recolor_opa(img, 150, LV_PART_MAIN);
set image zoom: lv_img_set_zoom(img, 512); /* zoom in 2 times*/
Set image rotation: lv_img_set_angle(img, 900); /* Rotate 90° clockwise */
Set the center point:
    lv_obj_update_layout(img); /* Update image layout information*/
    lv_img_set_pivot(img, 0, 0); /* Set the center point*/
Set the color and transparency of the slider body : lv_obj_set_style_bg_color(slider, lv_color_darken(color, 100), LV_PART_MAIN);   
update image parameters: lv_obj_update_layout(img);   

------------------------------------------------------colorwheel--------------------------------------------------- 

Set the currently selected color: lv_colorwheel_set_rgb(cw, lv_color_hex(0xff0000));
Get the currently selected color: lv_colorwheel_get_rgb(cw);
Set the color wheel mode:
    hue, saturation, lightness: lv_colorwheel_set_mode(cw, LV_COLORWHEEL_MODE_HUE/SATURATION/VAL UE);
    fixed color Ring mode: lv_colorwheel_set_mode_fixed(cw, true);
 ------------------------------------------- -------------- btnmatrix ----------------------------------- ---------------- 

Define the button array, the last element must be empty: static const char *map[] = { "btn1", "\n", "btn2", "btn3", "" }; set the button: lv_btnmatrix_set_map(btnm, map
) ;
Set button relative width: lv_btnmatrix_set_btn_width(btnm, id, width); /* Index (id) starts from 0, width 1~7 (default is 1) */Get index: lv_btnmatrix_get_selected_btn(btnm); Get text: lv_btnmatrix_get_btn_text
(    
btnm , id);
Set a single button attribute: lv_btnmatrix_set_btn_ctrl(btnm, id, LV_BTNMATRIX_CTRL_...);
Clear a single button attribute: lv_btnmatrix_clear_btn_ctrl(btnm, id, LV_BTNMATRIX_CTRL_...);    
Set all button attributes: lv_btnmatrix_set_bt n_ctrl_all(btnm, LV_BTNMATRIX_CTRL_.. .);

enum {     LV_BTNMATRIX_CTRL_HIDDEN, /* hidden */     LV_BTNMATRIX_CTRL_DISABLED, /* disabled */     LV_BTNMATRIX_CTRL_CHECKABLE, /* allow state switching */     LV_BTNMATRIX_CTRL_RECOLOR, /* allow text recoloring */ }; set single check attribute: lv_btnmat rix_set_one_checked(btnm, true) ; /* Note: You need to set the allowed state switching attribute first */





* Button matrix (optimized interface) */
    lv_obj_set_style_border_width(btnm, 0, LV_PART_MAIN); /* remove the main body border */
    lv_obj_set_style_bg_opa(btnm, 0, LV_PART_MAIN); /* set the main body background transparency */
    lv_obj_set_style_bg_opa(btnm, 0, LV_PART_ITEMS) ; /* Set button background transparency*/
    lv_obj_set_style_shadow_width(btnm, 0, LV_PART_ITEMS); /* Remove button shadow*/
    lv_obj_add_event_cb(btnm, b

 ------------------------------------------------------textarea--------------------------------------------------- 

 Add a character to the current cursor: lv_textarea_add_char(ta, 'A');
Add a string to the current cursor: lv_textarea_add_text(ta, "BCDEF"); 
Create a keyboard component: lv_obj_t *keyboard = lv_keyboard_create(lv_scr_act());
Association Keyboard and text area components: lv_keyboard_set_textarea(keyboard, ta);
set cursor position: lv_textarea_set_cursor_pos(ta, 0); /* 0: leftmost, LV_TEXTAREA_CURSOR_LAST: rightmost*/
delete text:
    lv_textarea_del_char(ta); /* delete One character to the left of the cursor */
    lv_textarea_del_char_forward(ta); /* delete one character to the right of the cursor */
set mode:
    lv_textarea_set_one_line(ta, true); /* single line mode */
    lv_textarea_set_password_mode(ta, true); /* password Mode (hide the input content) */
    lv_textarea_set_password_show_time(ta, 100); /* password display time */
limit character input:
    lv_textarea_set_accepted_chars(ta,"0123456789"); /* Limit the characters received*/
    lv_textarea_set_max_length(ta,6); /* Limit the character length*/
Set the placeholder: lv_textarea_set_placeholder_text(ta, "password"); /* Prompt for a password */
Get text: const char *txt = lv_textarea_get_text(ta); /* Get text box text*/ 
Compare text content: strcmp(const char *s1,const char *s2); /* When s1=s2, return 0 */
Create a keyboard: keyboard = lv_keyboard_create(lv_scr_act());
Associate the user name text box and keyboard: lv_keyboard_set_textarea(keyboard, target);

 ------------------------------------------------------keyboard---------------------------------------------------  

Create text area components: lv_obj_t *ta = lv_textarea_create(lv_scr_act());
associate keyboard and text area components: lv_keyboard_set_textarea(kb, ta);
allow button pop-up prompts: lv_keyboard_set_popovers(kb, true);
numeric keyboard mode: lv_keyboard_set_mode(kb , LV_KEYBOARD_MODE_NUMBER);
get mode: lv_keyboard_get_mode(target); 

 ------------------------------------------------------------------------------- ---- imgbtn ---------------------------------------------------- ------ 

Set the picture source of a certain state: lv_imgbtn_set_src(imgbtn, LV_IMGBTN_STATE_..., src_left, src_mid, src_right); //can set three pictures at the same time Set the
picture button size: lv_obj_set_size(imgbtn, 64 * 3, 64);    
set press State: lv_imgbtn_set_state(imgbtn, LV_IMGBTN_STATE_PRESSED);
How to display a picture with a transparency channel: Prepare a picture with a transparency channel, then recolor and set the transparency to 255.
Set image recolor transparency: lv_obj_set_style_img_recolor_opa(target, 255, 0); 
Set image recolor: lv_obj_set_style_img_recolor(target, lv_color_hex(0x00a9ff), 0); 

 -------------------------------------------------- ---- tabview ---------------------------------------------------- ------ 

Create a tab component: lv_obj_t *tabview = lv_tabview_create(parent, LV_DIR_..., tab_size);
Add a tab: lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1"); 
Set the currently selected tab: lv_tabview_set_act(tabview, 1, LV_ANIM_OFF); /* Index starts from 0*/
Unselected part: LV_STATE_DEFAULT For example, apply a font to all parts Selected
part: LV_STATE_CHECKED
Set button border width to 0: lv_obj_set_style_border_width(btn, 0, LV_PART_ITEMS| LV_STATE_CHECKED);
Get Button part: lv_obj_t *btn = lv_tabview_get_tab_btns(tabview); 
Get body part: lv_obj_t *obj = lv_tabview_get_content(tabview); 
Clear slide: lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
LV _PART_ITEMS: Buttons 

------------------------------------------------------tileview--------------------------------------------------- 

Create a tile view component: lv_obj_t *tileview = lv_tileview_create( parent );
add a page: lv_obj_t *tile1 = lv_tileview_add_tile( tileview, 0, 0, LV_DIR_RIGHT );
update parameters: lv_obj_update_layout( tileview );
set according to the page object: lv_obj_set_tile (tileview, tile2, LV_ANIM_OFF );
set according to the page rank: lv_obj_set_tile_id( tileview, 1, 0, LV_ANIM_OFF );
how many texts to set at the same time: lv_label_set_text(label_left,LV_SYMBOL_WIFI " 80%" LV_SYMBOL_BATTERY_3); 

------------------------------------------------------win---------------------------------------------------  

Create widget: lv_obj_t *win = lv_win_create(parent, header_height);
Add title: lv_obj_t *title = lv_win_add_title(win, "Setting");
Add button: lv_obj_t *btn = lv_win_add_btn(win, LV_SYMBOL_CLOSE, 20);
Add body content :
      Get subject: lv_obj_t *content = lv_win_get_content(win); 
      Add content: lv_obj_t *label = lv_label_create(content);    
Hide window: lv_obj_add_flag(win, LV_OBJ_FLAG_HIDDEN);
Clear display: lv_obj_clear_flag(win, LV_OBJ_FLAG_HIDDEN);
Set The color of the key symbol To set the text: lv_obj_set_style_text_color(btn_setting, lv_color_hex(0x000000), LV_STATE_DEFAULT); /* set the text color*/ 

------------------------------------------------------msgbox---------------------------------------------------  

 

 Create a message box widget:
    static const char *btns[] = { "Continue", "Close", "" };
    lv_obj_t *msgbox = lv_msgbox_create( lv_scr_act(), "Notice", "Do you want to continue?", btns , true );
close the message box: lv_msgbox_close(msgbox);
get the button index and text:
    lv_obj_t *target = lv_event_get_current_target(e); /* get the current trigger source, use current_target, use _target will be wrong*/
    lv_msgbox_get_active_btn(target); /* Get button index*/
    lv_msgbox_get_active_btn_text(target); /* Get button text*/
Get the smallest of the two: LV_MIN(lv_obj_get_width(obj);
remember to update, otherwise it won’t load: lv_obj_update_layout(msgbox_obj); 
       lv_style_set_radius(&style_bullet , LV_RADIUS_CIRCLE); //Set radius, pass in 'LV_RADIUS_CIRCLE'Intelligently judge
the user data drawn as a circle or passed in by the callback function: lv_obj_ * obj_color = (lv_obj_t *)e->user_data;
Message parts hide unused buttons:
      lv_obj_set_style_bg_opa(btn,0,LV_PART_ITEMS);
      lv_obj_set_style_shadow_width(btn,0,LV_PART_ITEMS);

------------------------------------------------------spinbox---------------------------------------------------  

 

Create a spinner component: lv_obj_t *spinbox = lv_spinbox_create(parent);
Increase the value: lv_spinbox_increment(spinbox);    
Decrement the value: lv_spinbox_decrement(spinbox);
Set the step value: lv_spinbox_set_step(spinbox, 200); /* Set the step value, default 1*/
set range value: lv_spinbox_set_range(spinbox, -1000, 1000);/* set range value, default ±99999*/
set current value: lv_spinbox_set_value(spinbox, 400);
set digital format: lv_spinbox_set_digit_format(spinbox, 4, 2); /* Set the number of digits and decimal point position*/
Set the cursor position: lv_spinbox_set_pos(spinbox, 3); //Use this function instead of using the set step value function
to get the current value: lv_spinbox_get_value(spinbox);/* Return The value is an integer, not a decimal*/    
Add an image to the button: lv_obj_set_style_bg_img_src(spinbox_btn1,LV_SYMBOL_PLUS,LV_PART_MAIN);
Integer into a decimal form: lv_label_set_text_fmt(parameter,"%s%d.%d",
                          spinbox_value < 0 ? "-" :"+",
                          spinbox_value / 10 < 0 ? -spinbox_value /10 : spinbox_value/10,
                          spinbox_value % 10 < 0 ? -spinbox_value % 10 : spinbox_value % 10);

------------------------------------------------------table---------------------------------------------------   

Create a table component: lv_obj_t *table = lv_table_create(parent);
set the number of rows: lv_table_set_row_cnt(table,2); 
set the number of columns: lv_table_set_col_cnt(table,2); 
set the width of the column: lv_table_set_col_width(table, 1, 200); 
set The content of the cell: lv_table_set_cell_value(table, 0, 0, "123");
formatted input, similar to printf: lv_table_set_cell_value_fmt(table, 1, 0, "%d", 100 );

#if 的用法:
#if (1 != LV_FONT_MONTSERRAT_38 || 1 != LV_FONT_MONTSERRAT_18 || 1 != LV_FONT_MONTSERRAT_20)
#error Please Make Sure Enable LV_FONT_MONTSERRAT_14 & LV_FONT_MONTSERRAT_18 & LV_FONT_MON TSERRAT_20
#endif

第一次见的算法:
 for (uint8_t i = 1; i < (10 >> 1) + 1; i++)
        lv_table_set_cell_value_fmt(table, 2 * i, 1, "Value %d", i - 1);
 for (uint8_t i = 1; i < (10 >> 1) + 2; i++)
        lv_table_set_cell_value_fmt(table, 2 * i - 1, 1, "Hide %d", i - 1);

Data:23.1.10

5、GUI-GURDER

 GUI GUIDER Application Notes_MR_Prometheus Blog-CSDN Blog_gui guider

LVGL-GUI Guider initial experience_Yunhai speechless blog-CSDN blog_gui-guider

LVGL | GUI-Guider use sharing_embedded hodgepodge blog-CSDN blog_gui-guider

Ten minutes to learn how to use lvgl designer gui guider and simulator to write a simple calculator application_哔哩哔哩_bilibili

Quick entry into the fourth phase of LVGL--Gui-Guuder use_哔哩哔哩_bilibili

Nanshanfu Embedded Blog_CSDN Blog - Play with STM32 Basics, FreeRTOS Basics, Sharing Domain

TIP: When compiling and running with VScode, the compilation fails because the system environment variable has a mingw compiler

 

 It can be removed before, but the speed of compiling and running with VScode is not as good as that of GUI-guider, so don't compile and run VScode later.

The implementation logic of a simple computer:

/**
 * @file custom.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include <stdio.h>
#include "lvgl.h"
#include "custom.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/

/**
 * Create a demo application
 */

static int get_result(int old,int oper,int value)
{
    int result = 0;
    switch (oper)
    {
    case 0:
        result = value;
        break;
    case 3:
        result = old + value;
        break;
    case 7:
        result = old - value;
        break;
    case 11:
        result = old*value;
        break;
    case 15:
        result = old/value;
        break;
    default:
        break;
    }
    return result;
}
void text_cb(lv_event_t* e)
{
    lv_ui * ui = lv_event_get_user_data(e);
    uint8_t id = lv_btnmatrix_get_selected_btn(ui->screen_btnm_1);
    const char * txt = lv_btnmatrix_get_btn_text(ui->screen_btnm_1,id);

    static int old = 0;
    static int oper = 0;
    int value = 0;
    static char num[10] = {0};


    switch (id)
    {
    case 3:
        printf("+\n");
        
    case 7:
        printf("-\n");
    case 11:
        printf("x\n");
    case 15:
        printf("/\n");
        sscanf(num,"%d",&value);                                //将现在显示的数字提取出来
        old = get_result(old,oper,value);                       //之前的内容运算出结果并保存
        lv_label_set_text_fmt(ui->screen_label_1,"%d",old);     //把之前的运算结果显示出
        oper = id ;                                             //保存当前的运算符
        memset(num,0,sizeof(num));                              //清空之前记录的显示缓存
        break;
    case 14:
        printf("=\n");
        sscanf(num,"%d",&value);                     //将现在显示的数字提取出来
        old = get_result(old,oper,value);            //之前的内容运算出结果并保存
        lv_label_set_text_fmt(ui->screen_label_1,"%d",old);   //把之前的运算结果显示出
        oper = 0 ;                                   //清空运算符
        old = 0;                                     //清空历史记录
        memset(num,0,sizeof(num));                   //清空之前记录的显示缓存
        break;
    case 12:
        printf("clean\n");
        lv_label_set_text(ui->screen_label_1,"");   //清除显示
        oper = 0 ;                                  //清空运算符
        old = 0;                                    //清空历史记录
        memset(num,0,sizeof(num));                  //清空之前记录的显示缓存
        break;
    default:
        printf("%s\n",txt);
        if (strlen(num)<sizeof(num)-1)
        {
            strcat(num,txt);
            lv_label_set_text(ui->screen_label_1,num);
        }
        
        break;
    }
}

void custom_init(lv_ui *ui)
{
    /* Add your codes here */
    lv_obj_add_event_cb(ui->screen_btnm_1,text_cb,LV_EVENT_PRESSED,ui);
}

23.1.5

6. Multi-screen switching, animation [esp32&lvgl]-2.6 #lvgl-multi-page (screen) setting/switching_lv_scr_load_anim_weixin_43326110's blog-CSDN blog 

6.2 Multi-screen switching

   /********tow_scr*************/
lv_obj_t * Scr_mainMenu;
lv_obj_t * Scr_wifi;
void Scr_1_cb(lv_event_t * e)
{
     lv_event_code_t code = lv_event_get_code(e);
     if(code == LV_EVENT_CLICKED)
     {
         /*设置页面加载动画*/
         lv_scr_load_anim(Scr_wifi, LV_SCR_LOAD_ANIM_NONE, 100, 0, false);
         lv_scr_load(Scr_wifi);
     }
}

void my_gui()
{
#if 1
    /********tow_scr*************/
    /*创建页面*/
    Scr_mainMenu = lv_obj_create(NULL);
    lv_obj_clean(Scr_mainMenu);
    lv_obj_remove_style_all(Scr_mainMenu);
    lv_obj_set_style_bg_opa(Scr_mainMenu, LV_OPA_COVER, 0);//0不透明
    lv_obj_set_style_bg_color(Scr_mainMenu, lv_color_hex(0xDaDaDa), 0);
    lv_obj_set_size(Scr_mainMenu, LV_HOR_RES, LV_VER_RES);
    lv_obj_t * Scr_1_btn = lv_btn_create(Scr_mainMenu);
    lv_obj_t * Scr_1_labl = lv_label_create(Scr_1_btn);
    lv_label_set_text(Scr_1_labl,"next page");
    lv_obj_add_event_cb(Scr_1_btn,Scr_1_cb,LV_EVENT_CLICKED,NULL);

    Scr_wifi = lv_obj_create(NULL);
    lv_obj_clean(Scr_wifi);
    lv_obj_remove_style_all(Scr_wifi);
    lv_obj_set_style_bg_opa(Scr_wifi, LV_OPA_COVER, 0);//0不透明
    lv_obj_set_style_bg_color(Scr_wifi, lv_color_hex(0x8a8a8a), 0);
    lv_obj_set_size(Scr_wifi, LV_HOR_RES, LV_VER_RES);
    lv_obj_t * Scr_2_btn = lv_btn_create(Scr_wifi);
    lv_obj_t * Scr_2_labl = lv_label_create(Scr_2_btn);
    lv_label_set_text(Scr_2_labl,"before page");
    lv_obj_add_event_cb(Scr_2_btn,Scr_2_cb,LV_EVENT_CLICKED,NULL);

    /*加载一个页面*/
    lv_scr_load(Scr_wifi);

#endif
}

6.2 Animation

/*******animation********/
static void anim_x_cb(void* var, int32_t v)
{
    lv_obj_set_x(var, v);
}

void my_gui()
{

#if 1
 /*******animation********/
/* 第一步:创建标签 */
 lv_obj_t* lv_obj = lv_label_create(lv_scr_act());
 lv_label_set_text(lv_obj,"ALIENTEK");
 lv_obj_set_pos(lv_obj, 400, 10);
 lv_obj_update_layout(lv_obj);
 /* 第二步:动画初始化 */
 lv_anim_t a;
 lv_anim_init(&a);
 /* 第三步:设置动画目标为标签对象 */
 lv_anim_set_var(&a, lv_obj);
 /* 第四步:设置动画起点和终点 */
 lv_anim_set_values(&a, lv_obj_get_x(lv_obj), 0);
 /* 第五步:设置动画时间 */
 lv_anim_set_time(&a, 5000);
 /* 第六步:设置动画回调函数 */
 lv_anim_set_exec_cb(&a, anim_x_cb);
 /* 第七步:设置动画轨道 */
 lv_anim_set_path_cb(&a, lv_anim_path_bounce);
 /* 第八步:设置动画轨道 */
 lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
 /* 第九步:开启动画 */
 lv_anim_start(&a);
}

LVGL Library Getting Started Tutorial- Animation- Frozen Candle- Blog Garden

6.3: Event bubbling

https://blog.csdn.net/qq_41650023/article/details/125260000

6.4: GUI-Guider write event callback

6.5: The code generated by GUI-Guider is ported to CodeBlocks

1. Create a new lvgl_app and copy and paste the custom and generated files generated by GUI-Guider.

2. Recursively add lvgl_app files in CodeBlocks

3. Compile and modify the newly added file header file problem

4. Add the relevant code of guider_ui to main

Reference article: LVGL-GUI Guider generation engineering transplantation Keil_gui guider transplantation_Yunhai Wuyu's Blog-CSDN Blog

Codeblocks add header file path contains _codeblocks header file path_dzdesigned's Blog-CSDN Blog

ESP32+LVGL Notes (2): Learning Calculator Routine at Station B_lvgl Design Calculator_hwd00001's Blog-CSDN Blog

GUI Guider and lvgl co-simulation (combined with stm32 experiments for demonstration, including touch screen experiment counters and calculators)

23.1.31 

The codeblock compilation problem has been found for almost a week. The code generated by GUI_Guider is transplanted to the codeblock. From time to time, No such file or directory appears at the end of the compilation. Sometimes it does not appear and sometimes it does. I have tried all kinds of methods to find the answer on the Internet to no avail. Finally, modify the file name to solve it? ? ? ? ? I suspect that the file name conflicts with gui_guider.h.

 

 

 

Normal operation after modification 

Header file names can be case-insensitive

 

23.2.28

The above problem is caused by the compiler not being able to find the generated image source file. Put the image folder in the outer layer of the working file and no error will be reported. The above problem does not exist under eclipse (22.3.8)

23.4.19

The above problem is the header file path problem

Correctly add header file settings

(85 messages) codeblocks add header file path contains-CSDN blog 

7. Page logic implementation

7.1: Set the front-end implementation of the page, page requirements, lvgl pop-up dialog box, only touch the dialog box is allowed, and other places are not allowed to touch. For example, the pop-up dialog box on the computer and mobile phone must be touched to close the current dialog box before touching other places.

method one:

1: First create the setting page and hide the page: lv_obj_add_flag(win,LV_OBJ_FLAG_HIDDEN): 

2: Clear the customs and click the setting button to display the setting page in the event lv_obj_clear_flag(win,LV_OBJ_FLAG_HIDDEN);

3: Put the setting page in the foreground: lv_obj_move_foreground(win);

4: Turn off the click event of the object behind: lv_obj_clear_flag(btn_win,LV_OBJ_FLAG_CLICKABLE);

/********win*************/
lv_obj_t * win;
lv_obj_t * btn_win;
void win_cb(lv_event_t * e)
{
    lv_obj_t * target = lv_event_get_target(e);
    lv_event_code_t event = lv_event_get_code(e);
    if(event == LV_EVENT_CLICKED)
    {
        lv_obj_add_flag(btn_win,LV_OBJ_FLAG_CLICKABLE);
        lv_obj_add_flag(win,LV_OBJ_FLAG_HIDDEN);
    }
}

void btn_cb(lv_event_t * e)
{
    lv_obj_t * target = lv_event_get_target(e);
    lv_event_code_t event = lv_event_get_code(e);
    if(event == LV_EVENT_CLICKED)
    {
        lv_obj_clear_flag(btn_win,LV_OBJ_FLAG_CLICKABLE);
        lv_obj_clear_flag(win,LV_OBJ_FLAG_HIDDEN);
        lv_obj_move_foreground(win);
    }
}

lv_obj_t * my_slider_creat(lv_obj_t * content,const char* symbol,lv_coord_t x_ofs,lv_coord_t y_ofs)
{
    lv_obj_t * slider = lv_slider_create(content);
    lv_obj_set_size(slider,scr_width/3,scr_hight/30);
    lv_slider_set_value(slider,50,LV_ANIM_OFF);
    lv_obj_align(slider, LV_ALIGN_CENTER,x_ofs,y_ofs);
    lv_obj_set_style_bg_color(slider,lv_color_hex(0x787c78), LV_PART_MAIN);
    lv_obj_set_style_bg_color(slider,lv_color_hex(0xc3c3c3), LV_PART_INDICATOR);
    lv_obj_remove_style(slider,NULL,LV_PART_KNOB);

    lv_obj_t * label = lv_label_create(content);
    lv_label_set_text(label,symbol);
    lv_obj_align_to(label,slider,LV_ALIGN_OUT_LEFT_MID,-10,0);

    return slider;

}

/********win*************/
void my_gui()
{

    win = lv_win_create(lv_scr_act(),scr_hight/12);
    lv_obj_set_size(win,scr_width*5/8,scr_hight*4/7);
    lv_obj_set_style_border_width(win,1,LV_STATE_DEFAULT);
    lv_obj_set_style_border_color(win,lv_color_hex(0x8a8a8a),LV_STATE_DEFAULT);
    lv_obj_set_style_border_opa(win,100,LV_STATE_DEFAULT);
    lv_obj_set_style_radius(win,10,LV_STATE_DEFAULT);
    lv_obj_center(win);

    lv_obj_t * btn_left = lv_win_add_btn(win,LV_SYMBOL_SETTINGS,20);
    lv_obj_set_style_bg_opa(btn_left,0,LV_STATE_DEFAULT);
    lv_obj_set_style_shadow_width(btn_left,0,LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(btn_left,lv_color_hex(0x000000),LV_STATE_DEFAULT);
    lv_obj_t * title = lv_win_add_title(win,"Setting");
    lv_obj_set_style_text_font(title,&lv_font_montserrat_18,LV_STATE_DEFAULT);
    lv_obj_add_flag(win,LV_OBJ_FLAG_HIDDEN);

    lv_obj_t * btn_right = lv_win_add_btn(win,LV_SYMBOL_CLOSE,20);
    lv_obj_set_style_bg_opa(btn_right,0,LV_STATE_DEFAULT);
    lv_obj_set_style_shadow_width(btn_right,0,LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(btn_right,lv_color_hex(0x000000),LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(btn_right,lv_color_hex(0xff0000),LV_STATE_PRESSED);
    lv_obj_add_event_cb(btn_right,win_cb,LV_EVENT_CLICKED,NULL);

    lv_obj_t * content = lv_win_get_content(win);
    lv_obj_t * slider_1 = my_slider_creat(content,LV_SYMBOL_AUDIO,15, -scr_hight/14);
    lv_obj_t * slider_2 = my_slider_creat(content,LV_SYMBOL_BELL,15, scr_hight/14);

    /*SET按键*/
    lv_obj_t * btn = lv_btn_create(lv_scr_act());
    lv_obj_align(btn,LV_ALIGN_BOTTOM_MID,0,0);
    lv_obj_t* label;
    label = lv_label_create(btn);
    lv_label_set_text(label, "Set");
    lv_obj_center(label);
    lv_obj_update_layout(label);
    lv_obj_add_event_cb(btn,btn_cb,LV_EVENT_CLICKED,NULL);


    lv_obj_t * obj_win = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj_win,400,300);
    btn_win = lv_btn_create(obj_win);
    lv_obj_align(btn_win,LV_ALIGN_OUT_LEFT_MID,0,0);

}

Method Two:

Using the modal dialog box, he set the button callback event to create a setting interface at the layer_top layer, and enabled the click property, layer_top will absorb all user clicks and act as a modal. The settings interface is deleted after the settings page is closed.

/**********模态对话框***********/
void close_btn_cb(lv_event_t * e)
{
    lv_obj_t * target = lv_event_get_target(e);
    lv_event_code_t event = lv_event_get_code(e);
    if(event == LV_EVENT_CLICKED)
    {
        lv_obj_del(win);           // 删除对象及其所有子对象
        win = NULL;
        lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);   // 清除标志
        lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_TRANSP, 0);  // 设置透明度
    }
}

static void ste_btn_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * ta = lv_event_get_target(e);

    if(code == LV_EVENT_CLICKED) {
            if(win == NULL) {
    //设置弹窗
    lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);                         // 使能 lv_layer_top 点击
    win = lv_win_create(lv_layer_top(),scr_hight/12);                               // 在 lv_layer_top 层上创建日历对象
    lv_obj_set_style_bg_opa(lv_layer_top(), LV_OPA_50, 0);                          // 设置对象透明度
    lv_obj_set_style_bg_color(lv_layer_top(), lv_palette_main(LV_PALETTE_GREY), 0); // 设置对象颜色
    lv_obj_set_size(win,scr_width*5/8,scr_hight*4/7);
    lv_obj_set_style_border_width(win,1,LV_STATE_DEFAULT);
    lv_obj_set_style_border_color(win,lv_color_hex(0x8a8a8a),LV_STATE_DEFAULT);
    lv_obj_set_style_border_opa(win,100,LV_STATE_DEFAULT);
    lv_obj_set_style_radius(win,10,LV_STATE_DEFAULT);
    lv_obj_center(win);

    //顶部左边设置logo
    lv_obj_t * btn_left = lv_win_add_btn(win,LV_SYMBOL_SETTINGS,20);
    lv_obj_set_style_bg_opa(btn_left,0,LV_STATE_DEFAULT);
    lv_obj_set_style_shadow_width(btn_left,0,LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(btn_left,lv_color_hex(0x000000),LV_STATE_DEFAULT);
    lv_obj_t * title = lv_win_add_title(win,"Setting");
    lv_obj_set_style_text_font(title,&lv_font_montserrat_18,LV_STATE_DEFAULT);

    //顶部右边关闭logo
    lv_obj_t * btn_right = lv_win_add_btn(win,LV_SYMBOL_CLOSE,20);
    lv_obj_set_style_bg_opa(btn_right,0,LV_STATE_DEFAULT);
    lv_obj_set_style_shadow_width(btn_right,0,LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(btn_right,lv_color_hex(0x000000),LV_STATE_DEFAULT);
    lv_obj_set_style_text_color(btn_right,lv_color_hex(0xff0000),LV_STATE_PRESSED);
    lv_obj_add_event_cb(btn_right,close_btn_cb,LV_EVENT_CLICKED,NULL);

    //滑块
    lv_obj_t * content = lv_win_get_content(win);
    lv_obj_t * slider_1 = my_slider_creat(content,LV_SYMBOL_AUDIO,15, -scr_hight/14);
    lv_obj_t * slider_2 = my_slider_creat(content,LV_SYMBOL_BELL,15, scr_hight/14);

        }
    }
}
/**********模态对话框***********/
void my_gui()
{

    lv_obj_t * btn = lv_btn_create(lv_scr_act());
    lv_obj_align(btn,LV_ALIGN_BOTTOM_MID,0,0);
    lv_obj_t* label;
    label = lv_label_create(btn);
    lv_label_set_text(label, "Set");
    lv_obj_center(label);
    lv_obj_update_layout(label);
    lv_obj_add_event_cb(btn,ste_btn_cb,LV_EVENT_CLICKED,NULL);

    lv_obj_t * bg_obj_win = lv_obj_create(lv_scr_act());
    lv_obj_set_size(bg_obj_win,400,300);
    btn_win = lv_btn_create(bg_obj_win);
    lv_obj_align(btn_win,LV_ALIGN_OUT_LEFT_MID,0,0);
}

 23.2.2

Reference article: icore4tlvgl_9 []

LVGL|lvgl Tutorial Skills Using Layers to Write Modal Dialog Boxes

8.mune menu control

This control is not mentioned in any video tutorials. Occasionally, I saw this control. In the V8.2 version, I found that the CodeBlock of the punctual atom is the 8.0 version, and there is no munu control. Instead, use the 8.2 project of Baiwen.com

LVGL 8.2 menu_lvgl menu_Xianjianqingyuan Blog-CSDN Blog

LVGL Library Getting Started Tutorial- Animation- Free Information

8.1 The problem of full content container

By default, adding components under content is not covered with margins

Solution: lv_style_set_pad_all 

    static lv_style_t cont_style;   // 容器的样式
	lv_style_init(&cont_style);
	lv_style_set_pad_all(&cont_style, 0);  // 铺满(新添加的一行代码)
	lv_obj_add_style(ui->screen_select_prescription_win_content, &cont_style, 0);
	lv_obj_set_size(ui->screen_select_prescription_list_1, 200,400*4/7);

Reference article: The flex layout of LVGL|lvgl tutorial covers the entire container (elastic layout covers the entire container)

23.2.9 

lvgl adds custom SYMBOL

8.2 menu related

8 encoders

How LVGL uses encoders - Zhihu (zhihu.com)

(71 messages) lvgl uses a rotary encoder as an external input device_lvgl encoder_I've been here.'s Blog-CSDN Blog

(71 messages) STM32 porting LVGL+rotary encoder interface docking_lvgl encoder_IMSHYANNE's Blog-CSDN Blog

[Open source] ESP32 Arduino LVGL8 encoder EC11 input demonstration demo_哔哩哔哩_bilibili

(86 messages) LVGL V8 application - switch pages by buttons_lvgl page switching_critical msp blog-CSDN blog

(86 messages) [LVGL] Study Notes--(3) Interface Switching and Display Optimization_lvgl Interface Switching_Gongzi Wuyuan's Blog-CSDN Blog

9 Themes

 0: for bright

 1: dark color

Set Theme: Pink

static const lv_font_t * font_normal;
lv_theme_default_init(NULL, lv_palette_main(LV_PALETTE_PINK), lv_palette_main(LV_PALETTE_BLUE), LV_THEME_DEFAULT_DARK, font_normal);

Default is blue:

 

 (85 messages) LVGL study notes 4 - theme Themes_lvgl theme-CSDN blog

static lv_style_t gThemeRectStyle;
static void new_theme_apply_cb(lv_theme_t* th, lv_obj_t* obj)
{
    if (lv_obj_check_type(obj, &lv_obj_class))
    {
        lv_obj_add_style(obj, &gThemeRectStyle, LV_STATE_DEFAULT);
    }
}
void set(){

    lv_obj_t* rect = lv_obj_create(lv_scr_act());
    lv_obj_set_size(rect, LV_PCT(20), LV_PCT(20));
    lv_obj_align(rect, LV_ALIGN_TOP_LEFT, 20, 20);

    /*Set a background color and a radius*/
    lv_style_init(&gThemeRectStyle);
    lv_style_set_radius(&gThemeRectStyle, 10);
    lv_style_set_bg_opa(&gThemeRectStyle, LV_OPA_COVER);
    lv_style_set_bg_color(&gThemeRectStyle, lv_palette_lighten(LV_PALETTE_RED, 1));

    /*Add a shadow*/
    lv_style_set_shadow_width(&gThemeRectStyle, 55);
    lv_style_set_shadow_color(&gThemeRectStyle, lv_palette_main(LV_PALETTE_BLUE));

    lv_obj_add_style(rect, &gThemeRectStyle, LV_PART_MAIN|LV_STATE_DEFAULT);

    /*通过当前主题初始化新主题*/
    lv_theme_t* th_active = lv_theme_get_from_obj(NULL);
    static lv_theme_t th_new;
    th_new = *th_active;

    /*设置父主题和新主题的样式适播放回调函数*/
    lv_theme_set_parent(&th_new, th_active);
    lv_theme_set_apply_cb(&th_new, new_theme_apply_cb);

    /*设置新主题*/
    lv_disp_set_theme(NULL, &th_new);

    lv_obj_t* rect2 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(rect2, LV_PCT(20), LV_PCT(20));
    lv_obj_align(rect2, LV_ALIGN_TOP_LEFT, 220, 20);

    lv_obj_t* rect3 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(rect3, LV_PCT(20), LV_PCT(20));
    lv_obj_align(rect3, LV_ALIGN_TOP_LEFT, 420, 20);
}

Guess you like

Origin blog.csdn.net/qq_45803449/article/details/128419441