3-2-1_按钮控件(lv_button)的用法

3-2-1_按钮控件(lv_button)的用法

Button(按钮) (lv_button)

Overview(概述)

文档位置:Button(按钮) (lv_button) — LVGL 文档

Button(按钮) (lv_button)

Overview(概述) 显示原文

Base object相比,按钮没有新功能。 它们可用于语义目的,并且默认设置略有不同。 默认情况下,按钮在以下方面与基础对象不同:

不可滚动

添加到默认组

默认高度和宽度设置为 LV_SIZE_CONTENT

Parts and Styles(零件和样式) 

LV_PART_MAIN按钮的背景。使用典型的背景样式属性。

code

创建按钮:

lv_obj_t *obj;

lv_button_t * btn;

obj=1v_obj_create(1v_screen_active ();

lv_obj_set_size(obj, 300,300);

btn=1v_button_create(obj);

lv_ label _t*1abe l=1 v_label _create(obj);

lv_obj_set_size(btn, 100,100);

label =1v_label_create(btn);

1v_ label_set_text(label ," Key1");

1v_obj_set_style_text_font(label,

&1v_font_source_han_sans_ bold_20, LV_PART_MAIN);

1v _obj_ set_ align(label, LV_ALIGN_CENTER);

结果:

增加事件

void lesson_3_2_1(void) {

lv_obj_t *obj;

lv_button_t * btn;

obj=lv_obj_create(lv_screen_active());

lv_obj_set_size(obj, 300, 300);

btn=lv_button_create(obj);

lv_label_t *label=lv_label_create(obj);

lv_obj_set_align(btn, LV_ALIGN_LEFT_MID);

lv_obj_set_size(btn, 100, 100);

label=lv_label_create(btn);

lv_label_set_text(label, "Key1");

lv_obj_set_style_text_font(label,

&lv_font_source_han_sans_bold_20, LV_PART_MAIN);

lv_obj_set_align(label, LV_ALIGN_CENTER);

/*LV_OBJ_FLAG_CHECKABLE:当对象被点击时切换已勾选状态(默认为红色)*/

lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);

/*创建事件回调函数*/

lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_ALL, NULL);

}

static void btn_event_handler(lv_event_t * e) {

lv_event_code_t code = lv_event_get_code(e);

/* LV_EVENT_CLICKED 如果未滚动,则在松开时调用(无论是否长按)*/

if(code == LV_EVENT_CLICKED) {

LV_LOG_USER("Clicked");

}

/* LV_EVENT_VALUE_CHANGED <对象的值已更改(即滑块移动)*/

else if(code == LV_EVENT_VALUE_CHANGED) {

LV_LOG_USER("Toggled");

}

}

结果:

室内环境

Key1

室内环境

Key1

课后思考

问题一:

既然按钮控件 与 基础对象 控件相⽐ ,没有新功能,创建接⼝也差不多,那按钮控件为什么 和基础对象控件(以及标签控件)的交互效果不⼀样。为什么会不⼀样呢?我们看到他们的 创建接⼝都是⼀样的,是在什么时候、哪⾥决定了他们不⼀样的样式呢?

/*

本质就是LVGL会给每一个控件一个默认的样式就是“主题”,LVGL在初始化时会加载一个默认 主题(如 lv_theme_default_init)。主题为每一种控件类(lv_button_class、

lv_label_class、lv_obj_class)都定义了默认样式。

当你用 lv_button_create(parent) 创建按钮时,LVGL内部会:

1. 分配一个 lv_obj_t 对象

2. 将该对象的类设置为 lv_button_class

3. 调用主题的 apply_cb 回调,根据对象的类来应用默认样式

基础对象(lv_obj_t)的类就是 lv_obj_class,它的默认样式比较简单(通常只有 背景色、边框等)。

按钮的类 lv_button_class 继承自 lv_obj_class,但主题为它单独定义了样式 (例如背景色不同、有阴影、按下时有动画等)。

所以即使创建接口相同(都是 lv_obj_create 的封装宏),对象的类不同,主题应用样式 时就产生了不同效果。

*/

// 主题的应用

lv_button_create

lv_obj_class_init_obj lv_theme_apply

apply_theme_recursion

apply_theme th->apply_cb

// 主题的初始化

lv_theme_default_init // lvgl\src\themes\default\lv_theme_default.c my_theme_t * theme = theme_def;

theme->base.apply_cb = theme_apply; 
style_init();

问题二:

能否在基础对象控件的基础上实现按钮控件的交互效果?

lv_obj_t *obj,*label;

obj= lv_obj_create(lv_screen_active());

lv_obj_center(obj);

label=lv_label_create(obj);

lv_label_set_text(label, "Button");

lv_obj_set_align(label, LV_ALIGN_CENTER);

lv_obj_set_size(obj, 100, 50);

static lv_style_t my_style;

static lv_style_t press_style;

/*样式初始化*/

/*样式步骤:定义样式及->初始化->设计样式->添加样式*/

lv_obj_style_init(&my_style);

/*默认创建的obj也是有阴影的 */

lv_style_set_shadow_width(&my_style, 5);

/**阴影的偏移 */

lv_style_set_shadow_offset_y(&my_style, 5);

lv_style_set_border_width(&my_style, 0);

/*设计父级字体样式子集的标签直接继承父级的 */

lv_style_set_text_color(&my_style, lv_color_white());

lv_style_set_bg_color(&my_style, lv_palette_main(LV_PALETTE_BLUE));

/*设计完之后必须添加样式 */

lv_obj_add_style(obj, &my_style, 0);

/**创建按下样式 */

lv_obj_style_init(&press_style);

lv_style_set_shadow_width(&press_style, 5);

lv_style_set_shadow_offset_y(&press_style, 5);

lv_style_set_border_width(&press_style, 0);

/**添加渐变,锥形渐变由中心点、起始角和结束角定义 */

lv_style_set_bg_grad_dir(&press_style, LV_GRAD_DIR_CONICAL);

lv_style_set_bg_grad_color(&press_style, lv_palette_main(LV_PALETTE_BLUE_GREY));

lv_style_set_size(&press_style, 120, 60);

lv_style_set_bg_color(&press_style, lv_palette_main(LV_PALETTE_BLUE));

lv_obj_add_style(obj, &press_style, LV_STATE_PRESSED);

上述图片为阴影默认都是有的这个可以偏移。

按下放大,不按时小的

Butt on

Button

上述加了渐变

/** 添加渐变,锥形渐变由中心点、起始角和结束角定义 * /

1v_style_set_bg_grad_dir( &pres s_style, LV_GRAD_DIR_CONICAL);

1v_style_set_bg_grad_color (&pres s_style,

1v_palette_ main(LV_PALETTE_BLUE_GREY));

/**

* The direction of the gradient.

梯度的方向。

*/

typedef enum {

LV_GRAD_DIR_NONE, /**<无渐变(grad_color属性被忽略)*/

LV_GRAD_DIR_VER, /**< 简单垂直(从上到下)渐变*/

LV_GRAD_DIR_HOR, /**< 简单水平(从左到右)渐变*/

LV_GRAD_DIR_LINEAR, /**<由起始点和终点定义的线性渐变。可以以任意角度 存在 .*/

LV_GRAD_DIR_RADIAL, /**< 由起始点和终点定义的线性渐变*/

LV_GRAD_DIR_CONICAL, /**< 由中心点、起始角度和结束角度定义的锥形渐变

*/

} lv_grad_dir_t;

问题三:

假如有很多个灯需要通过GUI控制(每个灯都能通过GUI单独控制亮灭),如何使⽤LVGL编 写这个GUI(快速编写出来并且代码简洁、易读)?深⼊思考:使⽤布局?使⽤其他控件?

/*创建9个按钮 */

lv_button_t * btn;

lv_obj_t * label;

#define BTN_PAD 20

int w = 0;

int h = 0;

int x = 0;

int y = 0;

for(int i=0; i < 9; i++)

{

btn = lv_button_create(lv_screen_active()); lv_obj_set_size(btn, 80, 40);

label = lv_label_create(btn);

lv_label_set_text_fmt(label, "Button%d", i); lv_obj_align(label, LV_ALIGN_CENTER,0,0);

lv_obj_update_layout(btn);

w= 1 v_obj_get_width(btn);

h= 1v_obj_get_height(btn);

if ((i %3) == 0)

X = 0 ;

y =(i/ 3)* (h + BTN_PAD);

else

X =(i%3 )*(w +BTN_PAD);

1v_obj_set_pos(btn,x,y);

问题四:

4. 按钮能不能是圆形或者方形指定圆角大小呢?

结果:

1v_obj_t *obj, * obj1;

/**创建一个黑色背景 */

obj = 1v_obj_ create(1v_screen_active ();

1v_obj_set_style _bg_color(obj ,1v_color_black (),0);

1v_obj_set_style_bg_opa(obj,LV_OPA_ 10, 0);

/*创建一个灰色小方块,用来容纳ble和wifi*/

obj1=lv_obj_create(obj);

lv_obj_set_style_bg_color(obj1, lv_color_hex(0X211917), 0); lv_obj_set_style_radius(obj1, 20, 0);

lv_obj_set_size(obj, 400, 400);

lv_obj_set_size(obj1, 140, 140);

lv_obj_center(obj);

/*添加按钮和图标 */

lv_obj_t *label;

lv_button_t * btn;

/*蓝牙图标*/

btn= lv_button_create(obj1);

lv_obj_set_size(btn,50 , 50);

lv_obj_align(btn, LV_ALIGN_TOP_RIGHT,0,0);

lv_obj_set_style_radius(btn, 37, LV_PART_MAIN);

label = lv_label_create(btn);

lv_label_set_text(label, LV_SYMBOL_BLUETOOTH);

lv_obj_set_style_text_font(label, &lv_font_montserrat_30, LV_PART_MAIN);

/*wifi 图标*/

btn= lv_button_create(obj1);

lv_obj_set_size(btn,50 , 50);

lv_obj_align(btn, LV_ALIGN_TOP_LEFT,0,0);

lv_obj_set_style_radius(btn, 37, LV_PART_MAIN);

label = lv_label_create(btn);

lv_label_set_text(label, LV_SYMBOL_WIFI);

lv_obj_set_style_text_font(label, &lv_font_montserrat_30, LV_PART_MAIN);

lv_obj_align(label, LV_ALIGN_CENTER,0,0);

posted @ 2026-07-30 18:05  哲别羽  阅读(4)  评论(0)    收藏  举报