嵌入式UI开发-lvgl+wsl2+vscode系列:8、控件(Widgets)(一)

ops/2024/9/24 13:18:35/

一、前言

这里将介绍一系列控件,了解后就可以开始基础的开发了。

二、示例

1、Base Obj(基础对象)

1.1、示例1
#include "../../lv_examples.h"
#if LV_BUILD_EXAMPLESvoid lv_example_obj_1(void)
{lv_obj_t * obj1;obj1 = lv_obj_create(lv_screen_active());lv_obj_set_size(obj1, 100, 50);lv_obj_align(obj1, LV_ALIGN_CENTER, -60, -30);static lv_style_t style_shadow;lv_style_init(&style_shadow);lv_style_set_shadow_width(&style_shadow, 10);lv_style_set_shadow_spread(&style_shadow, 5);lv_style_set_shadow_color(&style_shadow, lv_palette_main(LV_PALETTE_BLUE));lv_obj_t * obj2;obj2 = lv_obj_create(lv_screen_active());lv_obj_add_style(obj2, &style_shadow, 0);lv_obj_align(obj2, LV_ALIGN_CENTER, 60, 30);
}
#endif

image.png

1.2、示例2
#include "../../lv_examples.h"
#if LV_BUILD_EXAMPLESstatic void drag_event_handler(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_indev_t * indev = lv_indev_active();if(indev == NULL)  return;lv_point_t vect;lv_indev_get_vect(indev, &vect);int32_t x = lv_obj_get_x_aligned(obj) + vect.x;int32_t y = lv_obj_get_y_aligned(obj) + vect.y;lv_obj_set_pos(obj, x, y);
}/*** Make an object draggable.*/
void lv_example_obj_2(void)
{lv_obj_t * obj;obj = lv_obj_create(lv_screen_active());lv_obj_set_size(obj, 150, 100);lv_obj_add_event_cb(obj, drag_event_handler, LV_EVENT_PRESSING, NULL);lv_obj_t * label = lv_label_create(obj);lv_label_set_text(label, "Drag me");lv_obj_center(label);}
#endif

obj.gif

2、Arc(圆弧)

2.1、示例1
#include "../../lv_examples.h"#if LV_USE_ARC && LV_BUILD_EXAMPLESstatic void value_changed_event_cb(lv_event_t * e);void lv_example_arc_1(void)
{lv_obj_t * label = lv_label_create(lv_screen_active());/*Create an Arc*/lv_obj_t * arc = lv_arc_create(lv_screen_active());lv_obj_set_size(arc, 150, 150);lv_arc_set_rotation(arc, 135);lv_arc_set_bg_angles(arc, 0, 270);lv_arc_set_value(arc, 10);lv_obj_center(arc);lv_obj_add_event_cb(arc, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, label);/*Manually update the label for the first time*/lv_obj_send_event(arc, LV_EVENT_VALUE_CHANGED, NULL);
}static void value_changed_event_cb(lv_event_t * e)
{lv_obj_t * arc = lv_event_get_target(e);lv_obj_t * label = lv_event_get_user_data(e);lv_label_set_text_fmt(label, "%" LV_PRId32 "%%", lv_arc_get_value(arc));/*Rotate the label to the current position of the arc*/lv_arc_rotate_obj_to_angle(arc, label, 25);
}#endif

arc1.gif

2.2、示例2
#include "../../lv_examples.h"#if LV_USE_ARC && LV_BUILD_EXAMPLESstatic void set_angle(void * obj, int32_t v)
{lv_arc_set_value(obj, v);
}/*** Create an arc which acts as a loader.*/
void lv_example_arc_2(void)
{/*Create an Arc*/lv_obj_t * arc = lv_arc_create(lv_screen_active());lv_arc_set_rotation(arc, 270);lv_arc_set_bg_angles(arc, 0, 360);lv_obj_remove_style(arc, NULL, LV_PART_KNOB);   /*Be sure the knob is not displayed*/lv_obj_remove_flag(arc, LV_OBJ_FLAG_CLICKABLE);  /*To not allow adjusting by click*/lv_obj_center(arc);lv_anim_t a;lv_anim_init(&a);lv_anim_set_var(&a, arc);lv_anim_set_exec_cb(&a, set_angle);lv_anim_set_duration(&a, 1000);lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);    /*Just for the demo*/lv_anim_set_repeat_delay(&a, 500);lv_anim_set_values(&a, 0, 100);lv_anim_start(&a);}#endif

arc2.gif

3、bar(进度条)

3.1、示例1
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLESvoid lv_example_bar_1(void)
{lv_obj_t * bar1 = lv_bar_create(lv_screen_active());lv_obj_set_size(bar1, 200, 20);lv_obj_center(bar1);lv_bar_set_value(bar1, 70, LV_ANIM_OFF);
}#endif

image.png

3.2、示例2
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLES/*** Example of styling the bar*/
void lv_example_bar_2(void)
{static lv_style_t style_bg;static lv_style_t style_indic;lv_style_init(&style_bg);lv_style_set_border_color(&style_bg, lv_palette_main(LV_PALETTE_BLUE));lv_style_set_border_width(&style_bg, 2);lv_style_set_pad_all(&style_bg, 6); /*To make the indicator smaller*/lv_style_set_radius(&style_bg, 6);lv_style_set_anim_duration(&style_bg, 1000);lv_style_init(&style_indic);lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));lv_style_set_radius(&style_indic, 3);lv_obj_t * bar = lv_bar_create(lv_screen_active());lv_obj_remove_style_all(bar);  /*To have a clean start*/lv_obj_add_style(bar, &style_bg, 0);lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);lv_obj_set_size(bar, 200, 20);lv_obj_center(bar);lv_bar_set_value(bar, 100, LV_ANIM_ON);
}#endif

bar.gif

3.3、示例3
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLESstatic void set_temp(void * bar, int32_t temp)
{lv_bar_set_value(bar, temp, LV_ANIM_ON);
}/*** A temperature meter example*/
void lv_example_bar_3(void)
{static lv_style_t style_indic;lv_style_init(&style_indic);lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_RED));lv_style_set_bg_grad_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));lv_style_set_bg_grad_dir(&style_indic, LV_GRAD_DIR_VER);lv_obj_t * bar = lv_bar_create(lv_screen_active());lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);lv_obj_set_size(bar, 20, 200);lv_obj_center(bar);lv_bar_set_range(bar, -20, 40);lv_anim_t a;lv_anim_init(&a);lv_anim_set_exec_cb(&a, set_temp);lv_anim_set_duration(&a, 3000);lv_anim_set_playback_duration(&a, 3000);lv_anim_set_var(&a, bar);lv_anim_set_values(&a, -20, 40);lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);lv_anim_start(&a);
}#endif

bar2.gif

3.4、示例4
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLES/*** Bar with stripe pattern and ranged value*/
void lv_example_bar_4(void)
{LV_IMAGE_DECLARE(img_skew_strip);static lv_style_t style_indic;lv_style_init(&style_indic);lv_style_set_bg_image_src(&style_indic, &img_skew_strip);lv_style_set_bg_image_tiled(&style_indic, true);lv_style_set_bg_image_opa(&style_indic, LV_OPA_30);lv_obj_t * bar = lv_bar_create(lv_screen_active());lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);lv_obj_set_size(bar, 260, 20);lv_obj_center(bar);lv_bar_set_mode(bar, LV_BAR_MODE_RANGE);lv_bar_set_value(bar, 90, LV_ANIM_OFF);lv_bar_set_start_value(bar, 20, LV_ANIM_OFF);
}#endif

image.png

4.5、示例5
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLES/*** Bar with LTR and RTL base direction*/
void lv_example_bar_5(void)
{lv_obj_t * label;lv_obj_t * bar_ltr = lv_bar_create(lv_screen_active());lv_obj_set_size(bar_ltr, 200, 20);lv_bar_set_value(bar_ltr, 70, LV_ANIM_OFF);lv_obj_align(bar_ltr, LV_ALIGN_CENTER, 0, -30);label = lv_label_create(lv_screen_active());lv_label_set_text(label, "Left to Right base direction");lv_obj_align_to(label, bar_ltr, LV_ALIGN_OUT_TOP_MID, 0, -5);lv_obj_t * bar_rtl = lv_bar_create(lv_screen_active());lv_obj_set_style_base_dir(bar_rtl, LV_BASE_DIR_RTL, 0);lv_obj_set_size(bar_rtl, 200, 20);lv_bar_set_value(bar_rtl, 70, LV_ANIM_OFF);lv_obj_align(bar_rtl, LV_ALIGN_CENTER, 0, 30);label = lv_label_create(lv_screen_active());lv_label_set_text(label, "Right to Left base direction");lv_obj_align_to(label, bar_rtl, LV_ALIGN_OUT_TOP_MID, 0, -5);
}#endif

image.png

4.6、示例6
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLESstatic void set_value(void * bar, int32_t v)
{lv_bar_set_value(bar, v, LV_ANIM_OFF);
}static void event_cb(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_draw_label_dsc_t label_dsc;lv_draw_label_dsc_init(&label_dsc);label_dsc.font = LV_FONT_DEFAULT;char buf[8];lv_snprintf(buf, sizeof(buf), "%d", (int)lv_bar_get_value(obj));lv_point_t txt_size;lv_text_get_size(&txt_size, buf, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX,label_dsc.flag);lv_area_t txt_area;txt_area.x1 = 0;txt_area.x2 = txt_size.x - 1;txt_area.y1 = 0;txt_area.y2 = txt_size.y - 1;lv_bar_t * bar = (lv_bar_t *) obj;const lv_area_t * indic_area = &bar->indic_area;/*If the indicator is long enough put the text inside on the right*/if(lv_area_get_width(indic_area) > txt_size.x + 20) {lv_area_align(indic_area, &txt_area, LV_ALIGN_RIGHT_MID, -10, 0);label_dsc.color = lv_color_white();}/*If the indicator is still short put the text out of it on the right*/else {lv_area_align(indic_area, &txt_area, LV_ALIGN_OUT_RIGHT_MID, 10, 0);label_dsc.color = lv_color_black();}label_dsc.text = buf;label_dsc.text_local = true;lv_layer_t * layer = lv_event_get_layer(e);lv_draw_label(layer, &label_dsc, &txt_area);
}/*** Custom drawer on the bar to display the current value*/
void lv_example_bar_6(void)
{lv_obj_t * bar = lv_bar_create(lv_screen_active());lv_obj_set_size(bar, 200, 20);lv_obj_center(bar);lv_obj_add_event_cb(bar, event_cb, LV_EVENT_DRAW_MAIN_END, NULL);lv_anim_t a;lv_anim_init(&a);lv_anim_set_var(&a, bar);lv_anim_set_values(&a, 0, 100);lv_anim_set_exec_cb(&a, set_value);lv_anim_set_duration(&a, 4000);lv_anim_set_playback_duration(&a, 4000);lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);lv_anim_start(&a);}#endif

bar3.gif

4.7、示例7
#include "../../lv_examples.h"
#if LV_USE_BAR && LV_BUILD_EXAMPLES/*** Bar with opposite direction*/
void lv_example_bar_7(void)
{lv_obj_t * label;lv_obj_t * bar_tob = lv_bar_create(lv_screen_active());lv_obj_set_size(bar_tob, 20, 200);lv_bar_set_range(bar_tob, 100, 0);lv_bar_set_value(bar_tob, 70, LV_ANIM_OFF);lv_obj_align(bar_tob, LV_ALIGN_CENTER, 0, -30);label = lv_label_create(lv_screen_active());lv_label_set_text(label, "From top to bottom");lv_obj_align_to(label, bar_tob, LV_ALIGN_OUT_TOP_MID, 0, -5);
}#endif

image.png

4、button(按钮)略

按钮在最开始的三大控件那里已经介绍过了。

5、button matrix(矩阵按钮)

5.1、示例1
#include "../../lv_examples.h"
#if LV_USE_BUTTONMATRIX && LV_BUILD_EXAMPLESstatic void event_handler(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_target(e);if(code == LV_EVENT_VALUE_CHANGED) {uint32_t id = lv_buttonmatrix_get_selected_button(obj);const char * txt = lv_buttonmatrix_get_button_text(obj, id);LV_UNUSED(txt);LV_LOG_USER("%s was pressed\n", txt);}
}static const char * btnm_map[] = {"1", "2", "3", "4", "5", "\n","6", "7", "8", "9", "0", "\n","Action1", "Action2", ""};void lv_example_buttonmatrix_1(void)
{lv_obj_t * btnm1 = lv_buttonmatrix_create(lv_screen_active());lv_buttonmatrix_set_map(btnm1, btnm_map);lv_buttonmatrix_set_button_width(btnm1, 10, 2);        /*Make "Action1" twice as wide as "Action2"*/lv_buttonmatrix_set_button_ctrl(btnm1, 10, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_set_button_ctrl(btnm1, 11, LV_BUTTONMATRIX_CTRL_CHECKED);lv_obj_align(btnm1, LV_ALIGN_CENTER, 0, 0);lv_obj_add_event_cb(btnm1, event_handler, LV_EVENT_ALL, NULL);
}#endif

buttonmatrix.gif

5.2、示例2
#include "../../lv_examples.h"
#if LV_USE_BUTTONMATRIX && LV_BUILD_EXAMPLESstatic void event_cb(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;/*When the button matrix draws the buttons...*/if(base_dsc->part == LV_PART_ITEMS) {bool pressed = false;if(lv_buttonmatrix_get_selected_button(obj) == base_dsc->id1 && lv_obj_has_state(obj, LV_STATE_PRESSED)) {pressed = true;}/*Change the draw descriptor of the 2nd button*/if(base_dsc->id1 == 1) {lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);if(fill_draw_dsc) {fill_draw_dsc->radius = 0;if(pressed) fill_draw_dsc->color = lv_palette_darken(LV_PALETTE_BLUE, 3);else fill_draw_dsc->color = lv_palette_main(LV_PALETTE_BLUE);}lv_draw_box_shadow_dsc_t * box_shadow_draw_dsc = lv_draw_task_get_box_shadow_dsc(draw_task);if(box_shadow_draw_dsc) {box_shadow_draw_dsc->width = 6;box_shadow_draw_dsc->ofs_x = 3;box_shadow_draw_dsc->ofs_y = 3;}lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task);if(label_draw_dsc) {label_draw_dsc->color = lv_color_white();}}/*Change the draw descriptor of the 3rd button*/else if(base_dsc->id1 == 2) {lv_draw_fill_dsc_t * fill_draw_dsc = lv_draw_task_get_fill_dsc(draw_task);if(fill_draw_dsc) {fill_draw_dsc->radius = LV_RADIUS_CIRCLE;if(pressed) fill_draw_dsc->color = lv_palette_darken(LV_PALETTE_RED, 3);else fill_draw_dsc->color = lv_palette_main(LV_PALETTE_RED);}}else if(base_dsc->id1 == 3) {lv_draw_label_dsc_t * label_draw_dsc = lv_draw_task_get_label_dsc(draw_task);if(label_draw_dsc) {label_draw_dsc->opa = 0;}if(draw_task->type == LV_DRAW_TASK_TYPE_FILL) {LV_IMAGE_DECLARE(img_star);lv_image_header_t header;lv_result_t res = lv_image_decoder_get_info(&img_star, &header);if(res != LV_RESULT_OK) return;lv_area_t a;a.x1 = 0;a.x2 = header.w - 1;a.y1 = 0;a.y2 = header.h - 1;lv_area_align(&draw_task->area, &a, LV_ALIGN_CENTER, 0, 0);lv_draw_image_dsc_t img_draw_dsc;lv_draw_image_dsc_init(&img_draw_dsc);img_draw_dsc.src = &img_star;img_draw_dsc.recolor = lv_color_black();if(pressed) img_draw_dsc.recolor_opa = LV_OPA_30;lv_draw_image(base_dsc->layer, &img_draw_dsc, &a);}}}
}/*** Add custom drawer to the button matrix to customize buttons one by one*/
void lv_example_buttonmatrix_2(void)
{lv_obj_t * btnm = lv_buttonmatrix_create(lv_screen_active());lv_obj_add_event_cb(btnm, event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(btnm, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);lv_obj_center(btnm);
}#endif

image.png

5.3、示例3
#include "../../lv_examples.h"
#if LV_USE_BUTTONMATRIX  && LV_BUILD_EXAMPLESstatic void event_cb(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);uint32_t id = lv_buttonmatrix_get_selected_button(obj);bool prev = id == 0;bool next = id == 6;if(prev || next) {/*Find the checked button*/uint32_t i;for(i = 1; i < 7; i++) {if(lv_buttonmatrix_has_button_ctrl(obj, i, LV_BUTTONMATRIX_CTRL_CHECKED)) break;}if(prev && i > 1) i--;else if(next && i < 5) i++;lv_buttonmatrix_set_button_ctrl(obj, i, LV_BUTTONMATRIX_CTRL_CHECKED);}
}/*** Make a button group (pagination)*/
void lv_example_buttonmatrix_3(void)
{static lv_style_t style_bg;lv_style_init(&style_bg);lv_style_set_pad_all(&style_bg, 0);lv_style_set_pad_gap(&style_bg, 0);lv_style_set_clip_corner(&style_bg, true);lv_style_set_radius(&style_bg, LV_RADIUS_CIRCLE);lv_style_set_border_width(&style_bg, 0);static lv_style_t style_btn;lv_style_init(&style_btn);lv_style_set_radius(&style_btn, 0);lv_style_set_border_width(&style_btn, 1);lv_style_set_border_opa(&style_btn, LV_OPA_50);lv_style_set_border_color(&style_btn, lv_palette_main(LV_PALETTE_GREY));lv_style_set_border_side(&style_btn, LV_BORDER_SIDE_INTERNAL);lv_style_set_radius(&style_btn, 0);static const char * map[] = {LV_SYMBOL_LEFT, "1", "2", "3", "4", "5", LV_SYMBOL_RIGHT, ""};lv_obj_t * btnm = lv_buttonmatrix_create(lv_screen_active());lv_buttonmatrix_set_map(btnm, map);lv_obj_add_style(btnm, &style_bg, 0);lv_obj_add_style(btnm, &style_btn, LV_PART_ITEMS);lv_obj_add_event_cb(btnm, event_cb, LV_EVENT_VALUE_CHANGED, NULL);lv_obj_set_size(btnm, 225, 35);/*Allow selecting on one number at time*/lv_buttonmatrix_set_button_ctrl_all(btnm, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_clear_button_ctrl(btnm, 0, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_clear_button_ctrl(btnm, 6, LV_BUTTONMATRIX_CTRL_CHECKABLE);lv_buttonmatrix_set_one_checked(btnm, true);lv_buttonmatrix_set_button_ctrl(btnm, 1, LV_BUTTONMATRIX_CTRL_CHECKED);lv_obj_center(btnm);}#endif

buttonmatrix3.gif

6、Calendar(日历)

#include "../../lv_examples.h"
#if LV_USE_CALENDAR && LV_BUILD_EXAMPLESstatic void event_handler(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_current_target(e);if(code == LV_EVENT_VALUE_CHANGED) {lv_calendar_date_t date;if(lv_calendar_get_pressed_date(obj, &date)) {LV_LOG_USER("Clicked date: %02d.%02d.%d", date.day, date.month, date.year);}}
}void lv_example_calendar_1(void)
{lv_obj_t  * calendar = lv_calendar_create(lv_screen_active());lv_obj_set_size(calendar, 185, 230);lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 27);lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);lv_calendar_set_today_date(calendar, 2021, 02, 23);lv_calendar_set_showed_date(calendar, 2021, 02);/*Highlight a few days*/static lv_calendar_date_t highlighted_days[3];       /*Only its pointer will be saved so should be static*/highlighted_days[0].year = 2021;highlighted_days[0].month = 02;highlighted_days[0].day = 6;highlighted_days[1].year = 2021;highlighted_days[1].month = 02;highlighted_days[1].day = 11;highlighted_days[2].year = 2022;highlighted_days[2].month = 02;highlighted_days[2].day = 22;lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3);#if LV_USE_CALENDAR_HEADER_DROPDOWNlv_calendar_header_dropdown_create(calendar);
#elif LV_USE_CALENDAR_HEADER_ARROWlv_calendar_header_arrow_create(calendar);
#endif
}#endif

calendar.gif

7、Canvas(画布)

7.1、示例1
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH  200
#define CANVAS_HEIGHT  150void lv_example_canvas_1(void)
{lv_draw_rect_dsc_t rect_dsc;lv_draw_rect_dsc_init(&rect_dsc);rect_dsc.radius = 10;rect_dsc.bg_opa = LV_OPA_COVER;rect_dsc.bg_grad.dir = LV_GRAD_DIR_VER;rect_dsc.bg_grad.stops[0].color = lv_palette_main(LV_PALETTE_RED);rect_dsc.bg_grad.stops[0].opa = LV_OPA_100;rect_dsc.bg_grad.stops[1].color = lv_palette_main(LV_PALETTE_BLUE);rect_dsc.bg_grad.stops[1].opa = LV_OPA_50;rect_dsc.border_width = 2;rect_dsc.border_opa = LV_OPA_90;rect_dsc.border_color = lv_color_white();rect_dsc.shadow_width = 5;rect_dsc.shadow_offset_x = 5;rect_dsc.shadow_offset_y = 5;lv_draw_label_dsc_t label_dsc;lv_draw_label_dsc_init(&label_dsc);label_dsc.color = lv_palette_main(LV_PALETTE_ORANGE);label_dsc.text = "Some text on text canvas";/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf_16bpp, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_RGB565);lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf_16bpp);lv_obj_center(canvas);lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_area_t coords_rect = {30, 20, 100, 70};lv_draw_rect(&layer, &rect_dsc, &coords_rect);lv_area_t coords_text = {40, 80, 100, 120};lv_draw_label(&layer, &label_dsc, &coords_text);lv_canvas_finish_layer(canvas, &layer);/*Test the rotation. It requires another buffer where the original image is stored.*So use previous canvas as image and rotate it to the new canvas*/LV_DRAW_BUF_DEFINE(draw_buf_32bpp, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf_32bpp);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_canvas_fill_bg(canvas, lv_palette_lighten(LV_PALETTE_GREY, 1), LV_OPA_COVER);lv_canvas_init_layer(canvas, &layer);lv_image_dsc_t img;lv_draw_buf_to_image(&draw_buf_16bpp, &img);lv_draw_image_dsc_t img_dsc;lv_draw_image_dsc_init(&img_dsc);img_dsc.rotation = 120;img_dsc.src = &img;img_dsc.pivot.x = CANVAS_WIDTH / 2;img_dsc.pivot.y = CANVAS_HEIGHT / 2;lv_area_t coords_img = {0, 0, CANVAS_WIDTH - 1, CANVAS_HEIGHT - 1};lv_draw_image(&layer, &img_dsc, &coords_img);lv_canvas_finish_layer(canvas, &layer);
}#endif

image.png

7.2、示例2
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH  80
#define CANVAS_HEIGHT  40/*** Create a transparent canvas with transparency*/
void lv_example_canvas_2(void)
{lv_obj_set_style_bg_color(lv_screen_active(), lv_palette_lighten(LV_PALETTE_RED, 5), 0);/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_obj_center(canvas);/*Red background (There is no dedicated alpha channel in indexed images so LV_OPA_COVER is ignored)*/lv_canvas_fill_bg(canvas, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_COVER);/*Create hole on the canvas*/uint32_t x;uint32_t y;for(y = 10; y < 20; y++) {for(x = 5; x < 75; x++) {lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_50);}}for(y = 20; y < 30; y++) {for(x = 5; x < 75; x++) {lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_20);}}for(y = 30; y < 40; y++) {for(x = 5; x < 75; x++) {lv_canvas_set_px(canvas, x, y, lv_palette_main(LV_PALETTE_BLUE), LV_OPA_0);}}
}
#endif

image.png

7.3、示例3
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH  50
#define CANVAS_HEIGHT  50/*** Draw a rectangle to the canvas*/
void lv_example_canvas_3(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_rect_dsc_t dsc;lv_draw_rect_dsc_init(&dsc);dsc.bg_color = lv_palette_main(LV_PALETTE_RED);dsc.border_color = lv_palette_main(LV_PALETTE_BLUE);dsc.border_width = 3;dsc.outline_color = lv_palette_main(LV_PALETTE_GREEN);dsc.outline_width = 2;dsc.outline_pad = 2;dsc.outline_opa = LV_OPA_50;dsc.radius = 5;dsc.border_width = 3;lv_area_t coords = {10, 10, 40, 30};lv_draw_rect(&layer, &dsc, &coords);lv_canvas_finish_layer(canvas, &layer);
}
#endif

image.png

7.4、示例4
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_FONT_MONTSERRAT_14 && LV_BUILD_EXAMPLES#define CANVAS_WIDTH  50
#define CANVAS_HEIGHT  50/*** Draw a text to the canvas*/
void lv_example_canvas_4(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_label_dsc_t dsc;lv_draw_label_dsc_init(&dsc);dsc.color = lv_palette_main(LV_PALETTE_RED);dsc.font = &lv_font_montserrat_14;dsc.decor = LV_TEXT_DECOR_UNDERLINE;dsc.text = "Hello";lv_area_t coords = {10, 10, 30, 60};lv_draw_label(&layer, &dsc, &coords);lv_canvas_finish_layer(canvas, &layer);}
#endif

这里把原来的LV_FONT_MONTSERRAT_18改成LV_FONT_MONTSERRAT_14,lv_font_montserrat_18也改成lv_font_montserrat_14。
image.png
模拟环境一些依赖库没有。

7.5、示例5
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH  50
#define CANVAS_HEIGHT  50/*** Draw an arc to the canvas*/
void lv_example_canvas_5(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_arc_dsc_t dsc;lv_draw_arc_dsc_init(&dsc);dsc.color = lv_palette_main(LV_PALETTE_RED);dsc.width = 5;dsc.center.x = 25;dsc.center.y = 25;dsc.width = 10;dsc.radius = 15;dsc.start_angle = 0;dsc.end_angle = 220;lv_draw_arc(&layer, &dsc);lv_canvas_finish_layer(canvas, &layer);}
#endif

image.png

7.6、示例6
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#define CANVAS_WIDTH  50
#define CANVAS_HEIGHT  50/*** Draw an image to the canvas*/
void lv_example_canvas_6(void)
{/*Create a buffer for the canvas*/static uint8_t cbuf[LV_CANVAS_BUF_SIZE(CANVAS_WIDTH, CANVAS_HEIGHT, 32, LV_DRAW_BUF_STRIDE_ALIGN)];/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_buffer(canvas, cbuf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);LV_IMAGE_DECLARE(img_star);lv_draw_image_dsc_t dsc;lv_draw_image_dsc_init(&dsc);dsc.src = &img_star;lv_area_t coords = {10, 10, 10 + img_star.header.w - 1, 10 + img_star.header.h - 1};lv_draw_image(&layer, &dsc, &coords);
}
#endif

image.png

7.7、示例7
#include "../../lv_examples.h"
#if LV_USE_CANVAS&& LV_BUILD_EXAMPLES#define CANVAS_WIDTH  50
#define CANVAS_HEIGHT  50/*** Draw a line to the canvas*/
void lv_example_canvas_7(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_draw_line_dsc_t dsc;lv_draw_line_dsc_init(&dsc);dsc.color = lv_palette_main(LV_PALETTE_RED);dsc.width = 4;dsc.round_end = 1;dsc.round_start = 1;dsc.p1.x = 15;dsc.p1.y = 15;dsc.p2.x = 35;dsc.p2.y = 10;lv_draw_line(&layer, &dsc);lv_canvas_finish_layer(canvas, &layer);}
#endif

image.png

7.8、示例8
#include "../../lv_examples.h"
#if LV_USE_CANVAS && LV_BUILD_EXAMPLES#if LV_USE_VECTOR_GRAPHIC#define CANVAS_WIDTH  150
#define CANVAS_HEIGHT 150/*** Draw a path to the canvas*/
void lv_example_canvas_8(void)
{/*Create a buffer for the canvas*/LV_DRAW_BUF_DEFINE(draw_buf, CANVAS_WIDTH, CANVAS_HEIGHT, LV_COLOR_FORMAT_ARGB8888);/*Create a canvas and initialize its palette*/lv_obj_t * canvas = lv_canvas_create(lv_screen_active());lv_canvas_set_draw_buf(canvas, &draw_buf);lv_canvas_fill_bg(canvas, lv_color_hex3(0xccc), LV_OPA_COVER);lv_obj_center(canvas);lv_layer_t layer;lv_canvas_init_layer(canvas, &layer);lv_vector_dsc_t * dsc = lv_vector_dsc_create(&layer);lv_vector_path_t * path = lv_vector_path_create(LV_VECTOR_PATH_QUALITY_MEDIUM);lv_fpoint_t pts[] = {{10, 10}, {130, 130}, {10, 130}};lv_vector_path_move_to(path, &pts[0]);lv_vector_path_line_to(path, &pts[1]);lv_vector_path_line_to(path, &pts[2]);lv_vector_path_close(path);lv_vector_dsc_set_fill_color(dsc, lv_color_make(0x00, 0x80, 0xff));lv_vector_dsc_add_path(dsc, path);lv_draw_vector(dsc);lv_vector_path_delete(path);lv_vector_dsc_delete(dsc);lv_canvas_finish_layer(canvas, &layer);
}
#elsevoid lv_example_canvas_8(void)
{/*fallback for online examples*/lv_obj_t * label = lv_label_create(lv_screen_active());lv_label_set_text(label, "Vector graphics is not enabled");lv_obj_center(label);
}#endif /*LV_USE_VECTOR_GRAPHIC*/#endif

可以在lv_conf.h中开启对应扩展:
#define LV_USE_VECTOR_GRAPHIC 1
image.png
不开启矢量图扩展会提示:
image.png

8、chart(图表)

8.1、示例1
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLES/*** A very basic line chart*/
void lv_example_chart_1(void)
{/*Create a chart*/lv_obj_t * chart;chart = lv_chart_create(lv_screen_active());lv_obj_set_size(chart, 200, 150);lv_obj_center(chart);lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*//*Add two data series*/lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_PRIMARY_Y);lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_SECONDARY_Y);uint32_t i;for(i = 0; i < 10; i++) {/*Set the next points on 'ser1'*/lv_chart_set_next_value(chart, ser1, lv_rand(10, 50));/*Directly set points on 'ser2'*/ser2->y_points[i] = lv_rand(50, 90);}lv_chart_refresh(chart); /*Required after direct set*/
}#endif

image.png

8.2、示例2
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLES/*** Use lv_scale to add ticks to a scrollable chart*/
void lv_example_chart_2(void)
{/*Create a container*/lv_obj_t * main_cont = lv_obj_create(lv_screen_active());lv_obj_set_size(main_cont, 200, 150);lv_obj_center(main_cont);/*Create a transparent wrapper for the chart and the scale.*Set a large width, to make it scrollable on the main container*/lv_obj_t * wrapper = lv_obj_create(main_cont);lv_obj_remove_style_all(wrapper);lv_obj_set_size(wrapper, lv_pct(300), lv_pct(100));lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);/*Create a chart on the wrapper*Set it's width to 100% to fill the large wrapper*/lv_obj_t * chart = lv_chart_create(wrapper);lv_obj_set_width(chart, lv_pct(100));lv_obj_set_flex_grow(chart, 1);lv_chart_set_type(chart, LV_CHART_TYPE_BAR);lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 100);lv_chart_set_range(chart, LV_CHART_AXIS_SECONDARY_Y, 0, 400);lv_chart_set_point_count(chart, 12);lv_obj_set_style_radius(chart, 0, 0);/*Create a scale also with 100% width*/lv_obj_t * scale_bottom = lv_scale_create(wrapper);lv_scale_set_mode(scale_bottom, LV_SCALE_MODE_HORIZONTAL_BOTTOM);lv_obj_set_size(scale_bottom, lv_pct(100), 25);lv_scale_set_total_tick_count(scale_bottom, 12);lv_scale_set_major_tick_every(scale_bottom, 1);lv_obj_set_style_pad_hor(scale_bottom, lv_chart_get_first_point_center_offset(chart), 0);static const char * month[] = {"Jan", "Febr", "March", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec", NULL};lv_scale_set_text_src(scale_bottom, month);/*Add two data series*/lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_lighten(LV_PALETTE_GREEN, 2), LV_CHART_AXIS_PRIMARY_Y);lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_darken(LV_PALETTE_GREEN, 2), LV_CHART_AXIS_PRIMARY_Y);/*Set the next points on 'ser1'*/uint32_t i;for(i = 0; i < 12; i++) {lv_chart_set_next_value(chart, ser1, lv_rand(10, 60));lv_chart_set_next_value(chart, ser2, lv_rand(50, 90));}lv_chart_refresh(chart); /*Required after direct set*/
}#endif

image.png

8.3、示例3
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLESstatic void event_cb(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * chart = lv_event_get_target(e);if(code == LV_EVENT_VALUE_CHANGED) {lv_obj_invalidate(chart);}if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {int32_t * s = lv_event_get_param(e);*s = LV_MAX(*s, 20);}else if(code == LV_EVENT_DRAW_POST_END) {int32_t id = lv_chart_get_pressed_point(chart);if(id == LV_CHART_POINT_NONE) return;LV_LOG_USER("Selected point %d", (int)id);lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);while(ser) {lv_point_t p;lv_chart_get_point_pos_by_id(chart, ser, id, &p);int32_t * y_array = lv_chart_get_y_array(chart, ser);int32_t value = y_array[id];char buf[16];lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"$%d", value);lv_draw_rect_dsc_t draw_rect_dsc;lv_draw_rect_dsc_init(&draw_rect_dsc);draw_rect_dsc.bg_color = lv_color_black();draw_rect_dsc.bg_opa = LV_OPA_50;draw_rect_dsc.radius = 3;draw_rect_dsc.bg_image_src = buf;draw_rect_dsc.bg_image_recolor = lv_color_white();lv_area_t a;a.x1 = chart->coords.x1 + p.x - 20;a.x2 = chart->coords.x1 + p.x + 20;a.y1 = chart->coords.y1 + p.y - 30;a.y2 = chart->coords.y1 + p.y - 10;lv_layer_t * layer = lv_event_get_layer(e);lv_draw_rect(layer, &draw_rect_dsc, &a);ser = lv_chart_get_series_next(chart, ser);}}else if(code == LV_EVENT_RELEASED) {lv_obj_invalidate(chart);}
}/*** Show the value of the pressed points*/
void lv_example_chart_3(void)
{/*Create a chart*/lv_obj_t * chart;chart = lv_chart_create(lv_screen_active());lv_obj_set_size(chart, 200, 150);lv_obj_center(chart);lv_obj_add_event_cb(chart, event_cb, LV_EVENT_ALL, NULL);lv_obj_refresh_ext_draw_size(chart);/*Zoom in a little in X*///    lv_chart_set_scale_x(chart, 800);/*Add two data series*/lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_PRIMARY_Y);uint32_t i;for(i = 0; i < 10; i++) {lv_chart_set_next_value(chart, ser1, lv_rand(60, 90));lv_chart_set_next_value(chart, ser2, lv_rand(10, 40));}
}#endif

image.png

8.4、示例4
#include "../../lv_examples.h"#if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLESstatic void draw_event_cb(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part != LV_PART_ITEMS) {return;}lv_draw_fill_dsc_t * fill_dsc = lv_draw_task_get_fill_dsc(draw_task);if(fill_dsc) {lv_obj_t * chart = lv_event_get_target(e);int32_t * y_array = lv_chart_get_y_array(chart, lv_chart_get_series_next(chart, NULL));int32_t v = y_array[base_dsc->id2];uint32_t ratio = v * 255 / 100;fill_dsc->color = lv_color_mix(lv_palette_main(LV_PALETTE_GREEN), lv_palette_main(LV_PALETTE_RED), ratio);}
}/*** Recolor the bars of a chart based on their value*/
void lv_example_chart_4(void)
{/*Create a chart1*/lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_chart_set_type(chart, LV_CHART_TYPE_BAR);lv_chart_set_point_count(chart, 24);lv_obj_set_style_pad_column(chart, 2, 0);lv_obj_set_size(chart, 260, 160);lv_obj_center(chart);lv_chart_series_t * ser = lv_chart_add_series(chart, lv_color_hex(0xff0000), LV_CHART_AXIS_PRIMARY_Y);lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);uint32_t i;for(i = 0; i < 24; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 90));}
}#endif

image.png

8.5、示例5
#include "../../lv_examples.h"#if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLESstatic void hook_division_lines(lv_event_t * e);
static void add_faded_area(lv_event_t * e);
static void draw_event_cb(lv_event_t * e);/*** Add a faded area effect to the line chart and make some division lines ticker*/
void lv_example_chart_5(void)
{/*Create a chart*/lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/lv_obj_set_size(chart, 200, 150);lv_obj_set_style_pad_all(chart, 0, 0);lv_obj_set_style_radius(chart, 0, 0);lv_obj_center(chart);lv_chart_set_div_line_count(chart, 5, 7);lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);uint32_t i;for(i = 0; i < 10; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 80));}
}static void draw_event_cb(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part == LV_PART_ITEMS && draw_task->type == LV_DRAW_TASK_TYPE_LINE) {add_faded_area(e);}/*Hook the division lines too*/if(base_dsc->part == LV_PART_MAIN && draw_task->type == LV_DRAW_TASK_TYPE_LINE) {hook_division_lines(e);}
}static void add_faded_area(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;const lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL);/*Draw a triangle below the line witch some opacity gradient*/lv_draw_line_dsc_t * draw_line_dsc = draw_task->draw_dsc;lv_draw_triangle_dsc_t tri_dsc;lv_draw_triangle_dsc_init(&tri_dsc);tri_dsc.p[0].x = draw_line_dsc->p1.x;tri_dsc.p[0].y = draw_line_dsc->p1.y;tri_dsc.p[1].x = draw_line_dsc->p2.x;tri_dsc.p[1].y = draw_line_dsc->p2.y;tri_dsc.p[2].x = draw_line_dsc->p1.y < draw_line_dsc->p2.y ? draw_line_dsc->p1.x : draw_line_dsc->p2.x;tri_dsc.p[2].y = LV_MAX(draw_line_dsc->p1.y, draw_line_dsc->p2.y);tri_dsc.bg_grad.dir = LV_GRAD_DIR_VER;int32_t full_h = lv_obj_get_height(obj);int32_t fract_uppter = (int32_t)(LV_MIN(draw_line_dsc->p1.y, draw_line_dsc->p2.y) - obj->coords.y1) * 255 / full_h;int32_t fract_lower = (int32_t)(LV_MAX(draw_line_dsc->p1.y, draw_line_dsc->p2.y) - obj->coords.y1) * 255 / full_h;tri_dsc.bg_grad.stops[0].color = ser->color;tri_dsc.bg_grad.stops[0].opa = 255 - fract_uppter;tri_dsc.bg_grad.stops[0].frac = 0;tri_dsc.bg_grad.stops[1].color = ser->color;tri_dsc.bg_grad.stops[1].opa = 255 - fract_lower;tri_dsc.bg_grad.stops[1].frac = 255;lv_draw_triangle(base_dsc->layer, &tri_dsc);/*Draw rectangle below the triangle*/lv_draw_rect_dsc_t rect_dsc;lv_draw_rect_dsc_init(&rect_dsc);rect_dsc.bg_grad.dir = LV_GRAD_DIR_VER;rect_dsc.bg_grad.stops[0].color = ser->color;rect_dsc.bg_grad.stops[0].frac = 0;rect_dsc.bg_grad.stops[0].opa = 255 - fract_lower;rect_dsc.bg_grad.stops[1].color = ser->color;rect_dsc.bg_grad.stops[1].frac = 255;rect_dsc.bg_grad.stops[1].opa = 0;lv_area_t rect_area;rect_area.x1 = (int32_t)draw_line_dsc->p1.x;rect_area.x2 = (int32_t)draw_line_dsc->p2.x - 1;rect_area.y1 = (int32_t)LV_MAX(draw_line_dsc->p1.y, draw_line_dsc->p2.y) - 1;rect_area.y2 = (int32_t)obj->coords.y2;lv_draw_rect(base_dsc->layer, &rect_dsc, &rect_area);
}static void hook_division_lines(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;lv_draw_line_dsc_t * line_dsc = draw_task->draw_dsc;/*Vertical line*/if(line_dsc->p1.x == line_dsc->p2.x) {line_dsc->color  = lv_palette_lighten(LV_PALETTE_GREY, 1);if(base_dsc->id1 == 3) {line_dsc->width = 2;line_dsc->dash_gap = 0;line_dsc->dash_width = 0;}else {line_dsc->width = 1;line_dsc->dash_gap = 6;line_dsc->dash_width = 6;}}/*Horizontal line*/else {if(base_dsc->id1 == 2) {line_dsc->width  = 2;line_dsc->dash_gap  = 0;line_dsc->dash_width  = 0;}else {line_dsc->width = 2;line_dsc->dash_gap  = 6;line_dsc->dash_width  = 6;}if(base_dsc->id1 == 1  || base_dsc->id1 == 3) {line_dsc->color  = lv_palette_main(LV_PALETTE_GREEN);}else {line_dsc->color  = lv_palette_lighten(LV_PALETTE_GREY, 1);}}
}#endif

image.png

8.6、示例6
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLESstatic lv_obj_t * chart;
static lv_chart_series_t * ser;
static lv_chart_cursor_t * cursor;static void value_changed_event_cb(lv_event_t * e)
{static int32_t last_id = -1;lv_obj_t * obj = lv_event_get_target(e);last_id = lv_chart_get_pressed_point(obj);if(last_id != LV_CHART_POINT_NONE) {lv_chart_set_cursor_point(obj, cursor, NULL, last_id);}
}/*** Show cursor on the clicked point*/
void lv_example_chart_6(void)
{chart = lv_chart_create(lv_screen_active());lv_obj_set_size(chart, 200, 150);lv_obj_align(chart, LV_ALIGN_CENTER, 0, -10);//    lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 40);//    lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 10, 1, true, 30);lv_obj_add_event_cb(chart, value_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL);lv_obj_refresh_ext_draw_size(chart);cursor = lv_chart_add_cursor(chart, lv_palette_main(LV_PALETTE_BLUE), LV_DIR_LEFT | LV_DIR_BOTTOM);ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);uint32_t i;for(i = 0; i < 10; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 90));}//    lv_chart_set_scale_x(chart, 500);lv_obj_t * label = lv_label_create(lv_screen_active());lv_label_set_text(label, "Click on a point");lv_obj_align_to(label, chart, LV_ALIGN_OUT_TOP_MID, 0, -5);
}#endif

chart.gif

8.7、示例7
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_BUILD_EXAMPLESstatic void draw_event_cb(lv_event_t * e)
{lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part == LV_PART_INDICATOR) {lv_obj_t * obj = lv_event_get_target(e);lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL);lv_draw_rect_dsc_t * rect_draw_dsc = draw_task->draw_dsc;uint32_t cnt = lv_chart_get_point_count(obj);/*Make older value more transparent*/rect_draw_dsc->bg_opa = (LV_OPA_COVER *  base_dsc->id2) / (cnt - 1);/*Make smaller values blue, higher values red*/int32_t * x_array = lv_chart_get_x_array(obj, ser);int32_t * y_array = lv_chart_get_y_array(obj, ser);/*dsc->id is the tells drawing order, but we need the ID of the point being drawn.*/uint32_t start_point = lv_chart_get_x_start_point(obj, ser);uint32_t p_act = (start_point + base_dsc->id2) % cnt; /*Consider start point to get the index of the array*/lv_opa_t x_opa = (x_array[p_act] * LV_OPA_50) / 200;lv_opa_t y_opa = (y_array[p_act] * LV_OPA_50) / 1000;rect_draw_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_RED),lv_palette_main(LV_PALETTE_BLUE),x_opa + y_opa);}
}static void add_data(lv_timer_t * timer)
{LV_UNUSED(timer);lv_obj_t * chart = timer->user_data;lv_chart_set_next_value2(chart, lv_chart_get_series_next(chart, NULL), lv_rand(0, 200), lv_rand(0, 1000));
}/*** A scatter chart*/
void lv_example_chart_7(void)
{lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_obj_set_size(chart, 200, 150);lv_obj_align(chart, LV_ALIGN_CENTER, 0, 0);lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);lv_obj_set_style_line_width(chart, 0, LV_PART_ITEMS);   /*Remove the lines*/lv_chart_set_type(chart, LV_CHART_TYPE_SCATTER);lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_X, 0, 200);lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 1000);lv_chart_set_point_count(chart, 50);lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);uint32_t i;for(i = 0; i < 50; i++) {lv_chart_set_next_value2(chart, ser, lv_rand(0, 200), lv_rand(0, 1000));}lv_timer_create(add_data, 100, chart);
}#endif

chart2.gif

8.8、示例8
#include "../../lv_examples.h"
#if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLESstatic void add_data(lv_timer_t * t)
{lv_obj_t * chart = t->user_data;lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);lv_chart_set_next_value(chart, ser, lv_rand(10, 90));uint16_t p = lv_chart_get_point_count(chart);uint16_t s = lv_chart_get_x_start_point(chart, ser);int32_t * a = lv_chart_get_y_array(chart, ser);a[(s + 1) % p] = LV_CHART_POINT_NONE;a[(s + 2) % p] = LV_CHART_POINT_NONE;a[(s + 2) % p] = LV_CHART_POINT_NONE;lv_chart_refresh(chart);
}/*** Circular line chart with gap*/
void lv_example_chart_8(void)
{/*Create a stacked_area_chart.obj*/lv_obj_t * chart = lv_chart_create(lv_screen_active());lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_CIRCULAR);lv_obj_set_style_size(chart, 0, 0, LV_PART_INDICATOR);lv_obj_set_size(chart, 280, 150);lv_obj_center(chart);lv_chart_set_point_count(chart, 80);lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);/*Prefill with data*/uint32_t i;for(i = 0; i < 80; i++) {lv_chart_set_next_value(chart, ser, lv_rand(10, 90));}lv_timer_create(add_data, 300, chart);}#endif

chart3.gif

9、checkbox(复选框)

9.1、示例1
#include "../../lv_examples.h"
#if LV_USE_CHECKBOX && LV_BUILD_EXAMPLESstatic void event_handler(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_target(e);if(code == LV_EVENT_VALUE_CHANGED) {LV_UNUSED(obj);const char * txt = lv_checkbox_get_text(obj);const char * state = lv_obj_get_state(obj) & LV_STATE_CHECKED ? "Checked" : "Unchecked";LV_UNUSED(txt);LV_UNUSED(state);LV_LOG_USER("%s: %s", txt, state);}
}void lv_example_checkbox_1(void)
{lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);lv_obj_set_flex_align(lv_screen_active(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER);lv_obj_t * cb;cb = lv_checkbox_create(lv_screen_active());lv_checkbox_set_text(cb, "Apple");lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);cb = lv_checkbox_create(lv_screen_active());lv_checkbox_set_text(cb, "Banana");lv_obj_add_state(cb, LV_STATE_CHECKED);lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);cb = lv_checkbox_create(lv_screen_active());lv_checkbox_set_text(cb, "Lemon");lv_obj_add_state(cb, LV_STATE_DISABLED);lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);cb = lv_checkbox_create(lv_screen_active());lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);lv_checkbox_set_text(cb, "Melon\nand a new line");lv_obj_add_event_cb(cb, event_handler, LV_EVENT_ALL, NULL);lv_obj_update_layout(cb);
}#endif

checkbox.gif

9.2、示例2
#include "../../lv_examples.h"
#if LV_USE_CHECKBOX && LV_BUILD_EXAMPLESstatic lv_style_t style_radio;
static lv_style_t style_radio_chk;
static uint32_t active_index_1 = 0;
static uint32_t active_index_2 = 0;static void radio_event_handler(lv_event_t * e)
{uint32_t * active_id = lv_event_get_user_data(e);lv_obj_t * cont = lv_event_get_current_target(e);lv_obj_t * act_cb = lv_event_get_target(e);lv_obj_t * old_cb = lv_obj_get_child(cont, *active_id);/*Do nothing if the container was clicked*/if(act_cb == cont) return;lv_obj_remove_state(old_cb, LV_STATE_CHECKED);   /*Uncheck the previous radio button*/lv_obj_add_state(act_cb, LV_STATE_CHECKED);     /*Uncheck the current radio button*/*active_id = lv_obj_get_index(act_cb);LV_LOG_USER("Selected radio buttons: %d, %d", (int)active_index_1, (int)active_index_2);
}static void radiobutton_create(lv_obj_t * parent, const char * txt)
{lv_obj_t * obj = lv_checkbox_create(parent);lv_checkbox_set_text(obj, txt);lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE);lv_obj_add_style(obj, &style_radio, LV_PART_INDICATOR);lv_obj_add_style(obj, &style_radio_chk, LV_PART_INDICATOR | LV_STATE_CHECKED);
}/*** Checkboxes as radio buttons*/
void lv_example_checkbox_2(void)
{/* The idea is to enable `LV_OBJ_FLAG_EVENT_BUBBLE` on checkboxes and process the* `LV_EVENT_CLICKED` on the container.* A variable is passed as event user data where the index of the active* radiobutton is saved */lv_style_init(&style_radio);lv_style_set_radius(&style_radio, LV_RADIUS_CIRCLE);lv_style_init(&style_radio_chk);lv_style_set_bg_image_src(&style_radio_chk, NULL);uint32_t i;char buf[32];lv_obj_t * cont1 = lv_obj_create(lv_screen_active());lv_obj_set_flex_flow(cont1, LV_FLEX_FLOW_COLUMN);lv_obj_set_size(cont1, lv_pct(40), lv_pct(80));lv_obj_add_event_cb(cont1, radio_event_handler, LV_EVENT_CLICKED, &active_index_1);for(i = 0; i < 5; i++) {lv_snprintf(buf, sizeof(buf), "A %d", (int)i + 1);radiobutton_create(cont1, buf);}/*Make the first checkbox checked*/lv_obj_add_state(lv_obj_get_child(cont1, 0), LV_STATE_CHECKED);lv_obj_t * cont2 = lv_obj_create(lv_screen_active());lv_obj_set_flex_flow(cont2, LV_FLEX_FLOW_COLUMN);lv_obj_set_size(cont2, lv_pct(40), lv_pct(80));lv_obj_set_x(cont2, lv_pct(50));lv_obj_add_event_cb(cont2, radio_event_handler, LV_EVENT_CLICKED, &active_index_2);for(i = 0; i < 3; i++) {lv_snprintf(buf, sizeof(buf), "B %d", (int)i + 1);radiobutton_create(cont2, buf);}/*Make the first checkbox checked*/lv_obj_add_state(lv_obj_get_child(cont2, 0), LV_STATE_CHECKED);
}#endif

checkbox2.gif

10、dropdown(下拉列表)

10.1、示例1
#include "../../lv_examples.h"
#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLESstatic void event_handler(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_target(e);if(code == LV_EVENT_VALUE_CHANGED) {char buf[32];lv_dropdown_get_selected_str(obj, buf, sizeof(buf));LV_LOG_USER("Option: %s", buf);}
}void lv_example_dropdown_1(void)
{/*Create a normal drop down list*/lv_obj_t * dd = lv_dropdown_create(lv_screen_active());lv_dropdown_set_options(dd, "Apple\n""Banana\n""Orange\n""Cherry\n""Grape\n""Raspberry\n""Melon\n""Orange\n""Lemon\n""Nuts");lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 20);lv_obj_add_event_cb(dd, event_handler, LV_EVENT_ALL, NULL);
}#endif

image.png

10.2、示例2
#include "../../lv_examples.h"
#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLES/*** Create a drop down, up, left and right menus*/
void lv_example_dropdown_2(void)
{static const char * opts = "Apple\n""Banana\n""Orange\n""Melon";lv_obj_t * dd;dd = lv_dropdown_create(lv_screen_active());lv_dropdown_set_options_static(dd, opts);lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 10);dd = lv_dropdown_create(lv_screen_active());lv_dropdown_set_options_static(dd, opts);lv_dropdown_set_dir(dd, LV_DIR_BOTTOM);lv_dropdown_set_symbol(dd, LV_SYMBOL_UP);lv_obj_align(dd, LV_ALIGN_BOTTOM_MID, 0, -10);dd = lv_dropdown_create(lv_screen_active());lv_dropdown_set_options_static(dd, opts);lv_dropdown_set_dir(dd, LV_DIR_RIGHT);lv_dropdown_set_symbol(dd, LV_SYMBOL_RIGHT);lv_obj_align(dd, LV_ALIGN_LEFT_MID, 10, 0);dd = lv_dropdown_create(lv_screen_active());lv_dropdown_set_options_static(dd, opts);lv_dropdown_set_dir(dd, LV_DIR_LEFT);lv_dropdown_set_symbol(dd, LV_SYMBOL_LEFT);lv_obj_align(dd, LV_ALIGN_RIGHT_MID, -10, 0);
}#endif

dropdown.gif

10.3、示例3
#include "../../lv_examples.h"
#if LV_USE_DROPDOWN && LV_BUILD_EXAMPLESstatic void event_cb(lv_event_t * e)
{lv_obj_t * dropdown = lv_event_get_target(e);char buf[64];lv_dropdown_get_selected_str(dropdown, buf, sizeof(buf));LV_LOG_USER("'%s' is selected", buf);
}/*** Create a menu from a drop-down list and show some drop-down list features and styling*/
void lv_example_dropdown_3(void)
{/*Create a drop down list*/lv_obj_t * dropdown = lv_dropdown_create(lv_screen_active());lv_obj_align(dropdown, LV_ALIGN_TOP_LEFT, 10, 10);lv_dropdown_set_options(dropdown, "New project\n""New file\n""Save\n""Save as ...\n""Open project\n""Recent projects\n""Preferences\n""Exit");/*Set a fixed text to display on the button of the drop-down list*/lv_dropdown_set_text(dropdown, "Menu");/*Use a custom image as down icon and flip it when the list is opened*/LV_IMAGE_DECLARE(img_caret_down);lv_dropdown_set_symbol(dropdown, &img_caret_down);lv_obj_set_style_transform_rotation(dropdown, 1800, LV_PART_INDICATOR | LV_STATE_CHECKED);/*In a menu we don't need to show the last clicked item*/lv_dropdown_set_selected_highlight(dropdown, false);lv_obj_add_event_cb(dropdown, event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}#endif

dropdown2.gif

三、最后

接下来我们进行其他控件的总结,总共有三十类左右的控件,我们大体都过一遍,其他的UI开发其实都是可以触类旁通的。


http://www.ppmy.cn/ops/54881.html

相关文章

我对ChatGPT-5的期待

在科技飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们生活中不可或缺的一部分。尤其是近年来&#xff0c;随着ChatGPT等先进AI模型的推出&#xff0c;我们见证了AI技术在智能水平上的巨大飞跃。作为这一领域的最新成果&#xff0c;GPT-5的即将发布…

深入理解分布式搜索引擎 ElasticSearch,并能基于 ELK+Kafka 搭建分布式⽇志收集系统

Elasticsearch是一个基于Lucene的分布式、多租户能力的全文搜索引擎。它提供了RESTful web接口和分布式多用户能力的全文搜索引擎&#xff0c;基于Apache许可证发行。以下是对Elasticsearch的深入理解以及如何基于ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;加…

算法基础--------【图论】

图论&#xff08;待完善&#xff09; DFS:和回溯差不多 BFS:进while进行层序遍历 定义: 图论&#xff08;Graph Theory&#xff09;是研究图及其相关问题的数学理论。图由节点&#xff08;顶点&#xff09;和连接这些节点的边组成。图论的研究范围广泛&#xff0c;涉及路径、…

Vue 全局状态管理新宠:Pinia实战指南

文章目录 前言全局状态管理基本步骤&#xff1a;pinia 前言 随着Vue.js项目的日益复杂&#xff0c;高效的状态管理变得至关重要。Pinia作为Vue.js官方推荐的新一代状态管理库&#xff0c;以其简洁的API和强大的功能脱颖而出。本文将带您快速上手Pinia&#xff0c;从安装到应用&…

#如何使用 Qt 5.6 在 Android 上启用 NFC

如何使用 Qt 5.6 在 Android 上启用 NFC NFC 技术在 Android 应用开发中变得越来越重要。在本文中&#xff0c;我将介绍如何使用 Qt 5.6 来实现 Android 上的 NFC 功能。这个教程基于一个创建于 8 年 8 个月前的问题&#xff0c;并在 7 年 3 个月前进行了修改&#xff0c;讨论…

熊猫烧香是什么?

熊猫烧香&#xff08;Worm.WhBoy.cw&#xff09;是一种由李俊制作的电脑病毒&#xff0c;于2006年底至2007年初在互联网上大规模爆发。这个病毒因其感染后的系统可执行文件图标会变成熊猫举着三根香的模样而得名。熊猫烧香病毒具有自动传播、自动感染硬盘的能力&#xff0c;以及…

Electron去掉窗口边框并添加关闭按钮

在 Electron 中&#xff0c;如果你想去掉默认的窗口边框&#xff08;frame&#xff09;并添加额外的按键&#xff0c;你可以通过以下步骤来实现&#xff1a; 去掉默认的窗口边框&#xff1a; 使用 BrowserWindow 的 frame 选项&#xff0c;并将其设置为 false 来创建一个无边…

spl实现循环计算

需求 需要对一批数据进行价格计算 这里面的一部分单价来自于历史记录&#xff0c;但是另外一部分的单价&#xff0c;需要边计算边存储 数据库结构 CREATE TABLE tbl_mix_trace_price (lot_id_out varchar(255) DEFAULT NULL COMMENT 产出,lot_id_in varchar(255) DEFAULT NULL…