【LVGL】部件 - 基础对象

引言

仅作笔记分享。

LVGL 编程思想

LVGL 采用的是面向对象的编程思想,以抽象的类来实例化不同的对象(部件)

举例

image

实现流程

C 语言中没有“类”的概念,LVGL 以结构体的形式来实现“类”的思想。

过程:

  1. 使用lv_obj_t结构体实例化一个具体的对象:lv_obj(基础对象),默认就是以当前活动的屏幕作为基础对象。
  2. 这个基础对象作为父对象衍生出更多的子对象:lv_switchlv_lablelv_slider...这些部件。
  3. 父对象衍生出这些子对象后,子对象就会继承很多父对象的属性以及行为,后面就可以用一套同意的 api 函数对这些属性和行为进行管理。

image

void my_gui(void)
{
    lv_obj_t* switch1 = lv_switch_create(lv_scr_act());	// 创建一个在当前活动屏幕作为父对象的子对象开关switch1
    lv_obj_set_size(switch_obj, 120, 60);		// 设置开关部件大小
    lv_obj_t* switch2 = lv_switch_create(switch1);	// 可以选择活动屏幕或者前面的switch1来继承,若选择了switch2则与switch2只有命令关系,与活动屏幕才是父子关系
}

现象:

image

父子对象规律

  1. 用一个父对象创建出一个子对象时,父对象就是子对象的容器,子对象装在父对象中。
  2. 用一个父对象创建出一个子对象时,子对象默认创建在父对象的左上角。

基础对象简介

基础对象(lv_obj)可以作为父对象,来创建其他对象,同时也可以作为部件使用。

image

举例

void my_gui(void)
{
    lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj1, 300, 400);
}

现象:

image

父对象和子对象的关系

image

举例

void my_gui(void)
{
    lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj1, 300, 300);
    lv_obj_set_pos(obj1, 20, 20);

    lv_obj_t *obj2 = lv_obj_create(obj1);
    lv_obj_set_pos(obj2, 150, 150);
}

现象:
注意,不显示的区域可以拖动控件画面来看。

image

部件的基本属性

image

一、大小

image

部件大小(size)相关 API 函数

设置宽度:lv_obj_set_width(obj, new_width);
设置高度:lv_obj_set_height(obj, new_height);
同时设置宽度、高度:lv_obj_set_size(obj, new_width, new_height);

举例

void my_gui(void)
{
    lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
    lv_obj_set_width(obj1, 200);
    lv_obj_set_height(obj1, 400);
}

现象:

image

二、位置

image


image

部件位置(pos)相关 API 函数

设置X轴坐标:lv_obj_set_x(obj, new_x);
设置Y轴坐标:lv_obj_set_y(obj, new_y);
同时设置X、Y轴坐标:lv_obj_set_pos(obj, new_x, new_y);

举例

void my_gui(void)
{
    lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
    lv_obj_set_width(obj1, 200);
    lv_obj_set_height(obj1, 400);
}

现象:

image

三、对齐

image

对齐相关 API 函数

方式一:
参照父对象对齐:lv_obj_set_align(obj, LV_ALIGN_...);
参照父对象对齐,再进行偏移:lv_obj_align(obj, LV_ALIGN_..., x, y);
方式二:
参照其他对象对齐(无父子关系),再进行偏移:
lv_obj_align_to(obj_to_align, obj_referece, LV_ALIGN_..., x, y);
                基准对象       需要对齐的对象   对齐模式

对齐模式

有些对齐模式在某些对齐方式下是不支持的,例如参照父对象对齐的时候,不能在外部对齐。

image

举例

方式一

void my_gui(void)
{
    lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
    lv_obj_set_align(obj1, LV_ALIGN_CENTER);
    lv_obj_align(obj1, LV_ALIGN_BOTTOM_MID, 50, 50);
}
// 这里采用向底部对齐的方式,假如再采用偏移的话,其实是会超出父对象的显示范围

现象:

image

方式二

void my_gui(void)
{
    lv_obj_t* obj1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(obj1, 300, 300);
    lv_obj_t* obj2 = lv_obj_create(lv_scr_act());
    lv_obj_align_to(obj2, obj1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
}
// 以方式二来对齐,则可以选择全部的对齐模式,但是还是需要考虑到父对象的显示范围

现象:

image

四、样式

image

1. 添加样式

普通样式

举例
添加普通样式:
// 定义的变量只能是全局的、静态的或动态分配的,不能是局部的,否则样式容易失效
static lv_style_t style; 				/* 定义样式变量 */
lv_style_init(&style); 					/* 初始化样式 */
lv_style_set_bg_color(&style, lv_color_hex(0xf4b183)); 	/* 设置背景颜色 */
lv_obj_t * obj = lv_obj_create(lv_scr_act()); 		/* 创建一个部件 */
lv_obj_add_style(obj, & style, LV_STATE_DEFAULT); 	/* 设置部件的样式 */
		 部件  样式     样式选择器
// 优点:共享

现象:

image

本地样式

举例
添加本地样式:
lv_obj_t * obj = lv_obj_create(lv_scr_act()); 				/* 创建一个部件 */
lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183),LV_STATE_DEFAULT);/* 设置部件的样式 */
			  部件  样式                    样式选择器
// 优点:简单
// 缺点:只能应用到某一个部件上,无法全局共享

现象:

image

2. 样式生效状态

image

举例

void my_gui(void)
{
    lv_obj_t * obj = lv_obj_create(lv_scr_act()); 			     /* 创建一个部件 */
    lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183), LV_STATE_HOVERED);/* 设置鼠标悬停状态触发样式 */
    // 注意,这里设置的是鼠标悬停状态触发样式,在 PC 上生效,但是实际在触摸屏上还是不行的,注意这一点,这里只是方便演示
}

3. 样式属性

image

查找相应样式 api 函数

写出一个普通或本地样式的 api 函数,然后查找定义即可跳转至 api 函数文件。

api 函数说明

可以在官网上寻找开发手册,查找某一个 api 函数的使用方法和功能。以下是官方开发手册:

LVGL 官方开发手册

举例

void my_gui(void)
{
    lv_obj_t * obj1 = lv_obj_create(lv_scr_act());      /* 创建一个部件 */
    lv_obj_set_align(obj1, LV_ALIGN_CENTER);        /* 设置部件对齐模式 */

    lv_obj_set_style_border_color(obj1, lv_color_hex(0x56c621), LV_STATE_DEFAULT);  /* 设置部件边框颜色 */
    lv_obj_set_style_border_width(obj1, 10, LV_STATE_DEFAULT);      /* 设置部件边框宽度 */
    lv_obj_set_style_border_opa(obj1, 50, LV_STATE_DEFAULT);        /* 设置部件边框透明度(越小越透明) */

    lv_obj_set_style_outline_color(obj1, lv_color_hex(0x9aca21), LV_STATE_DEFAULT);  /* 设置部件轮廓颜色 */
    lv_obj_set_style_outline_width(obj1, 10, LV_STATE_DEFAULT);      /* 设置部件轮廓宽度 */
    lv_obj_set_style_outline_opa(obj1, 200, LV_STATE_DEFAULT);       /* 设置部件轮廓透明度(越小越透明) */
    // 设置边框和轮廓的方法非常相近,只不过api函数所在的位置不一样而已
}

现象:

image

4. 单独设置部件中某个部分的样式

image

如何查看某个部件由什么部分组成

参见:

LVGL 官方开发手册

举例

void my_gui(void)
{
    lv_obj_t * slider = lv_slider_create(lv_scr_act());      /* 创建一个滑块 */
    lv_obj_set_align(slider, LV_ALIGN_CENTER);          /* 将滑块居中 */

    lv_obj_set_style_bg_color(slider, lv_color_hex(0x49bc40), LV_STATE_DEFAULT | LV_PART_INDICATOR);    /* 设置指示器样式颜色 */
    lv_obj_set_style_bg_color(slider, lv_color_hex(0x49bc40), LV_STATE_DEFAULT | LV_PART_KNOB);             /* 设置手柄样式颜色 */
    // 设置一个部件不同部分,要分两行代码单独设置
}

现象:

image

五、事件

image

事件相关 api 函数

添加事件:lv_obj_add_event_cb(obj, event_cb, event_code, user_data);
				事件回调函数  事件类型	用户数据
删除事件:lv_obj_remove_event_cb(obj,  event_cb);

事件类型

参见:

LVGL 官方开发手册

image

举例

#include "lvgl.h"
#include "stdio.h"
#include "my_gui.h"

static void my_event_cb(lv_event_t * e)
{
    printf("LV_EVENT_CLICKED \r\n");
}

void my_gui(void)
{
    lv_obj_t * obj1 = lv_obj_create(lv_scr_act());                                              /* 创建一个部件 */
    lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_CLICKED, NULL);     /* 对象按下后触发事件 */
}

现象:

image

1. 不同事件类型共用一个事件回调函数

image

程序:

点击查看代码
#include "lvgl.h"
#include "stdio.h"
#include "my_gui.h"

static void my_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_CLICKED) {
        printf(" 事件类型:按下后释放 \r\n");
    } else if (code == LV_EVENT_LONG_PRESSED) {
        printf(" 事件类型:按下(长按) \r\n");
    }
}

void my_gui(void)
{
    lv_obj_t * obj1 = lv_obj_create(lv_scr_act());                                                          /* 创建一个部件 */
    lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_CLICKED, NULL);                 /* 对象按下后触发事件 */
    lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_LONG_PRESSED, NULL);      /* 对象长按触发事件 */
}

现象:

image

2. 不同部件共用一个事件回调函数

image

程序:

点击查看代码
#include "lvgl.h"
#include "stdio.h"
#include "my_gui.h"

lv_obj_t *obj1, *obj2;

static void my_event_cb(lv_event_t * e)
{
    lv_obj_t *target = lv_event_get_target(e);
    if (target == obj1) {
        printf(" obj1按下释放触发事件 \r\n");
    } else if (target == obj2) {
        printf(" obj2长按触发事件 \r\n");
    }
}

void my_gui(void)
{
    obj1 = lv_obj_create(lv_scr_act());                                                          /* 创建一个部件 */
    lv_obj_add_event_cb(obj1, my_event_cb, LV_EVENT_CLICKED, NULL);                 /* 对象按下后触发事件 */
    lv_obj_set_size(obj1, 200, 200);

    obj2 = lv_obj_create(lv_scr_act());                                                          /* 创建一个部件 */
    lv_obj_add_event_cb(obj2, my_event_cb, LV_EVENT_LONG_PRESSED, NULL);     /* 对象按下后触发事件 */
    lv_obj_set_size(obj2, 100, 100);
}

现象:
image

博客导航

博客导航

posted @ 2025-11-06 17:25  膝盖中箭卫兵  阅读(5)  评论(0)    收藏  举报
ORCID iD icon https://orcid.org/0000-0001-5102-772X