1. Video quick start
Quick Start LVGL (based on STM32, LVGL 8.2.0)_mucherry's blog-CSDN blog_lvgl
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
Lecture 7 Basics - LVGL Transplantation (No Operating System 4)_哔哩哔哩_bilibili
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
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
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
8.2 menu related
8 encoders
How LVGL uses encoders - Zhihu (zhihu.com)
[Open source] ESP32 Arduino LVGL8 encoder EC11 input demonstration demo_哔哩哔哩_bilibili
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);
}