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);



浙公网安备 33010602011771号