0
点赞
收藏
分享

微信扫一扫

LVGL v8学习笔记 | 05 - LVGL基础知识

自信的姐姐 2022-03-23 阅读 75


一、lvgl对象

1. 基础对象(lv_obj_t)

在lvgl中,任何控件都是一个对象。这些控件都继承自lvgl基础对象类,换句话说,​lvgl基础类描述了所有控件共有的属性和方法​,称之为​​lv_obj_t​​。

lv_obj_t类定义在文件​​lvgl\src\core\lv_obj.h​​文件中,定义如下:

typedef struct _lv_obj_t {
const lv_obj_class_t * class_p;
struct _lv_obj_t * parent;
_lv_obj_spec_attr_t * spec_attr;
_lv_obj_style_t * styles;
#if LV_USE_USER_DATA
void * user_data;
#endif
lv_area_t coords;
lv_obj_flag_t flags;
lv_state_t state;
uint16_t layout_inv : 1;
uint16_t scr_layout_inv : 1;
uint16_t skip_trans : 1;
uint16_t style_cnt : 6;
uint16_t h_layout : 1;
uint16_t w_layout : 1;
} lv_obj_t;

一上来就抛源码是一种很不道德的行为,我只是想展示lvgl基础对象长什么样子~

2. 基础对象的属性

在lvgl中,一个控件对象具有两种属性,一种是继承自基础对象的属性,另一些是控件特有的一些属性。

基础对象的属性有:

  • Position
  • Size
  • Parent
  • Drag enable
  • Click enable

我们可以通过​​lv_obj_set_xxx​​​和​​lv_obj_get_xxx​​API来设置或者获取这些属性。

2.1. 控件大小

只改变宽度:

/**
* Set the width of an object
* @param obj pointer to an object
* @param w the new width
* @note possible values are:
* pixel simple set the size accordingly
* LV_SIZE_CONTENT set the size to involve all children in the given direction
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
* x should be in [0..1000]% range
*/
void lv_obj_set_width(struct _lv_obj_t * obj, lv_coord_t w);

只改变高度:

/**
* Set the height of an object
* @param obj pointer to an object
* @param h the new height
* @note possible values are:
* pixel simple set the size accordingly
* LV_SIZE_CONTENT set the size to involve all children in the given direction
* lv_pct(x) to set size in percentage of the parent's content area size (the size without paddings).
* x should be in [0..1000]% range
*/
void lv_obj_set_height(struct _lv_obj_t * obj, lv_coord_t h);

同时改变宽度和高度:

/**
* Set the size of an object.
* @param obj pointer to an object
* @param w the new width
* @param h the new height
* @note possible values are:
* pixel simple set the size accordingly
* LV_SIZE_CONTENT set the size to involve all children in the given direction
* LV_SIZE_PCT(x) to set size in percentage of the parent's content area size (the size without paddings).
* x should be in [0..1000]% range
*/
void lv_obj_set_size(struct _lv_obj_t * obj, lv_coord_t w, lv_coord_t h);

这里的大小参数有点意思,有三种值可以设置:

  • pixel:直接设置像素点的值
  • LV_SIZE_CONTENT:设置为包含给定方向上的所有子控件的大小
  • LV_SIZE_PCT(x):按照父控件大小的百分比来设置

2.2. 控件位置

同样,设置控件的API也提供了三个:

/**
* Set the x coordinate of an object
* @param obj pointer to an object
* @param x new x coordinate
* @note With default alignment it's the distance from the top left corner
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
* @note The position is interpreted on the content area of the parent
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
*/
void lv_obj_set_x(struct _lv_obj_t * obj, lv_coord_t x);

/**
* Set the y coordinate of an object
* @param obj pointer to an object
* @param y new y coordinate
* @note With default alignment it's the distance from the top left corner
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
* @note The position is interpreted on the content area of the parent
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
*/
void lv_obj_set_y(struct _lv_obj_t * obj, lv_coord_t y);
/**
* Set the position of an object relative to the set alignment.
* @param obj pointer to an object
* @param x new x coordinate
* @param y new y coordinate
* @note With default alignment it's the distance from the top left corner
* @note E.g. LV_ALIGN_CENTER alignment it's the offset from the center of the parent
* @note The position is interpreted on the content area of the parent
* @note The values can be set in pixel or in percentage of parent size with `lv_pct(v)`
*/
void lv_obj_set_pos(struct _lv_obj_t * obj, lv_coord_t x, lv_coord_t y);

x,y参数的值默认对齐到左上角,而且该位置是在父控件的区域上解释,同样,有两种设置方法:

  • pixel:直接设置像素点的值
  • lv_pct(v):根据父控件区域的百分比来设置

eg1. 设置控件大小为,宽度是父控件的50%,高度是父控件的50%。

void lv_study_object1(void)
{
lv_obj_t *obj = lv_obj_create(lv_scr_act());

// 设置控件大小
lv_obj_set_size(obj, lv_pct(50), lv_pct(50));
// 设置控件位置
lv_obj_set_pos(obj, lv_pct(20), lv_pct(20));

}

这样一个最简单的示例运行起来后,效果如图:

LVGL v8学习笔记 | 05 - LVGL基础知识_加载

3. 创建-删除对象

在lvgl中,对象可以被动态的创建和删除,这意味着只有当前创建的控件会消耗RAM。

例如,当你需要一个chart控件时,可以在需要的时候创建它,并在不需要的时候删除它。

(1)对象创建API

每个对象类型(每种控件)都有它自己的创建API和统一的原型,如下:

lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other parameters if any>);

创建API有一个参数:

  • parent:指向父对象的指针

返回值为 ​lv_obj_t 类型的指针,所有的控件都可以用此指针来指向​。

(2)对象删除API

所有对象类型的删除API是统一的,如下:

void lv_obj_del(lv_obj_t * obj);

该API将会​立即​删除​该对象和它所有的子对象​。

如果不想理解删除,比如想在子对象的​​LV_EVENT_DELETE​​时间中删除父对象,可以使用下面的API:

lv_obj_del_async(lv_obj_t * obj);

如果仅仅想移除某个对象的所有子对象,可以使用下面的API:

void lv_obj_clean(lv_obj_t * obj);

二、lvgl屏幕(Screens)

1. 创建screens

屏幕(Screens)是一种特殊的对象,​它没有父对象​,创建一个屏幕如下:

lv_obj_t * scr1 = lv_obj_create(NULL);

屏幕可以被创建为任何对象类型,比如基础对象或者一张用作壁纸的图片。

2. 获取当前活动的屏幕

lvgl默认创建并加载了一个基础对象作为屏幕,要获取当前活动的屏幕,可以使用 ​​lv_scr_act()​​ API。

/**
* Get the active screen of the default display
* @return pointer to the active screen
*/
static inline lv_obj_t * lv_scr_act(void);

3. 加载新屏幕

要加载一个新屏幕,API如下:

static inline void lv_scr_load(lv_obj_t * scr);

4. 动画加载屏幕

加载一个新屏幕的时候可以带上动画,使用下面的API:

/**
* Switch screen with animation
* @param scr pointer to the new screen to load
* @param anim_type type of the animation from `lv_scr_load_anim_t`. E.g. `LV_SCR_LOAD_ANIM_MOVE_LEFT`
* @param time time of the animation
* @param delay delay before the transition
* @param auto_del true: automatically delete the old screen
*/
void lv_scr_load_anim(lv_obj_t * scr, lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del);

参数意义如下:

  • scr:指向新屏幕的指针
  • anim_type:动画类型
  • time:动画时间
  • delay:延迟时间后,动画开始,新屏幕变为当前活动屏幕
  • auto_del:当动作结束时,是否自动删除旧的屏幕

其中​动画类型anim_type支持以下值​:

typedef enum {
LV_SCR_LOAD_ANIM_NONE,
LV_SCR_LOAD_ANIM_OVER_LEFT,
LV_SCR_LOAD_ANIM_OVER_RIGHT,
LV_SCR_LOAD_ANIM_OVER_TOP,
LV_SCR_LOAD_ANIM_OVER_BOTTOM,
LV_SCR_LOAD_ANIM_MOVE_LEFT,
LV_SCR_LOAD_ANIM_MOVE_RIGHT,
LV_SCR_LOAD_ANIM_MOVE_TOP,
LV_SCR_LOAD_ANIM_MOVE_BOTTOM,
LV_SCR_LOAD_ANIM_FADE_ON,
} lv_scr_load_anim_t;

eg2. 动画加载新屏幕

void lv_study_object1(void)
{
lv_obj_t* obj = lv_obj_create(lv_scr_act());

// 设置控件大小
lv_obj_set_size(obj, lv_pct(50), lv_pct(50));
// 设置控件位置
lv_obj_set_pos(obj, lv_pct(20), lv_pct(20));

// 创建新屏幕
lv_obj_t* scr2 = lv_obj_create(NULL);

// 动画加载新屏幕
lv_scr_load_anim(scr2, LV_SCR_LOAD_ANIM_MOVE_RIGHT, 2000, 2000, true);

// 创建新屏幕上的控件
lv_obj_t* obj2 = lv_obj_create(scr2);
lv_obj_set_size(obj2, lv_pct(20), lv_pct(20));
lv_obj_set_pos(obj2, lv_pct(50), lv_pct(50));
}

LVGL v8学习笔记 | 05 - LVGL基础知识_lvgl_02

三、控件的Parts

Parts实在想不到用什么中文翻译~

一个控件可以包含多个Parts,比如按钮只有一个主Parts,而活动条则由背景、指示块,旋钮三个Parts组成。

Parts的名称组成结构为​​LV_ + <TYPE> _PART_ <NAME>​​​,比如 ​​LV_BTN_PART_MAIN​​​ 和 ​​LV_SLIDER_PART_KNOB​​。

Parts通常在给对象添加风格(style)时使用,通过Parts可以给控件的不同Parts分别添加不同的Style​。

四、对象的状态

对象的状态可以是下列状态中的一个或者多个:

  • ​LV_STATE_DEFAULT​​ Normal, released state
  • ​LV_STATE_CHECKED​​ Toggled or checked state
  • ​LV_STATE_FOCUSED​​ Focused via keypad or encoder or clicked via touchpad/mouse
  • ​LV_STATE_FOCUS_KEY​​ Focused via keypad or encoder but not via touchpad/mouse
  • ​LV_STATE_EDITED​​ Edit by an encoder
  • ​LV_STATE_HOVERED​​ Hovered by mouse (not supported now)
  • ​LV_STATE_PRESSED​​ Being pressed
  • ​LV_STATE_SCROLLED​​ Being scrolled
  • ​LV_STATE_DISABLED​​ Disabled state
  • ​LV_STATE_USER_1​​ Custom state
  • ​LV_STATE_USER_2​​ Custom state
  • ​LV_STATE_USER_3​​ Custom state
  • ​LV_STATE_USER_4​​ Custom state

状态通常是由lvgl自动切换的,但也可以手动改变状态,要完全覆盖当前状态,可以使用下面的API:

/**
* Set the state (fully overwrite) of an object.
* If specified in the styles, transition animations will be started from the previous state to the current.
* @param obj pointer to an object
* @param state the new state
*/
static void lv_obj_set_state(lv_obj_t * obj, lv_state_t new_state);

五、快照

可以为对象及其子对象生成快照。

lvgl思维导图

  • ​​【腾讯文档】lvgl​​

LVGL v8学习笔记 | 05 - LVGL基础知识_加载_03



举报

相关推荐

0 条评论