Objects(对象)
显示原文
In LVGL the basic building blocks of a user interface are the objects, also called Widgets. For example a Button, Label, Image, List, Chart or Text area.
You can see all the Object types here.
All objects are referenced using an lv_obj_t
pointer as a handle.
This pointer can later be used to set or get the attributes of the
object.
在LVGL中,用户界面的 基本组成部分 是对象,也称为 控件。例如,一个 按钮、标签、图像、列表、图表 或者 文本区域。
您可以在这里查看所有的 对象类型。
所有的对象都使用 lv_obj_t
类型的指针作为句柄进行引用。之后可以使用该指针来设置或获取对象的属性。
Attributes(属性)
Basic attributes(基本属性)
显示原文
All object types share some basic attributes:
Position
Size
Parent
Styles
Event handlers
Etc
You can set/get these attributes with lv_obj_set_...
and
lv_obj_get_...
functions. For example:
/*Set basic object attributes*/
lv_obj_set_size(btn1, 100, 50); /*Set a button's size*/
lv_obj_set_pos(btn1, 20,30); /*Set a button's position*/
To see all the available functions visit the Base object's documentation.
所有的对象类型都有一些通用的基本属性:
位置
大小
父对象
样式
事件处理程序
等等
您可以使用 lv_obj_set_...
和 lv_obj_get_...
函数设置或者获取这些属性。例如:
/*设置基本对象属性*/
lv_obj_set_size(btn1, 100, 50); /*设置按钮的大小*/
lv_obj_set_pos(btn1, 20,30); /*设置按钮的位置*/
您可以在这里查看所有的函数接口:基本对象的文档。
Specific attributes(特殊属性)
显示原文
The object types have special attributes too. For example, a slider has
Minimum and maximum values
Current value
For these special attributes, every object type may have unique API functions. For example for a slider:
/*Set slider specific attributes*/
lv_slider_set_range(slider1, 0, 100); /*Set the min. and max. values*/
lv_slider_set_value(slider1, 40, LV_ANIM_ON); /*Set the current value (position)*/
The API of the widgets is described in their Documentation but you can also check the respective header files (e.g. widgets/lv_slider.h)
对象类型也有特殊的属性。例如,滑块有:
最小值和最大值
当前值
针对这些特殊属性,每个对象类型可能有独特的API函数。例如,对于滑块:
/*设置滑块特定属性*/
lv_slider_set_range(slider1, 0, 100); /*设置最小值和最大值*/
lv_slider_set_value(slider1, 40, LV_ANIM_ON); /*设置当前值(位置)*/
所有控件的API在它们各自的 文档 中有描述,但您也可以查看相应的头文件(例如, widgets/lv_slider.h)
Working mechanisms(工作机制)
Parent-child structure(父子结构)
显示原文
A parent object can be considered as the container of its children. Every object has exactly one parent object (except screens), but a parent can have any number of children. There is no limitation for the type of the parent but there are objects which are typically a parent (e.g. button) or a child (e.g. label).
一个父对象可以被视为其子对象的容器。每个对象都都必须会有且仅有一个父对象(屏幕除外),但一个父对象可以有任意数量的子对象。 父对象的类型没有限制,但是有些对象一般是父对象(例如按钮)或者是子对象(例如标签)。
Moving together(一起移动)
显示原文
If the position of a parent changes, the children will move along with it. Therefore, all positions are relative to the parent.
lv_obj_t * parent = lv_obj_create(lv_screen_active()); /*Create a parent object on the current screen*/
lv_obj_set_size(parent, 100, 80); /*Set the size of the parent*/
lv_obj_t * obj1 = lv_obj_create(parent); /*Create an object on the previously created parent object*/
lv_obj_set_pos(obj1, 10, 10); /*Set the position of the new object*/
Modify the position of the parent:
lv_obj_set_pos(parent, 50, 50); /*Move the parent. The child will move with it.*/
(For simplicity the adjusting of colors of the objects is not shown in the example.)
如果父对象的位置改变,子对象也会随之移动。因此,所有子对象的位置都是相对于父对象而言的。
lv_obj_t * parent = lv_obj_create(lv_screen_active()); /* 在当前屏幕上创建一个父对象 */
lv_obj_set_size(parent, 100, 80); /* 设置父对象的大小 */
lv_obj_t * obj1 = lv_obj_create(parent); /* 在先前创建的父对象上创建一个对象 */
lv_obj_set_pos(obj1, 10, 10); /* 设置新对象的位置 */
修改父对象的位置:
lv_obj_set_pos(parent, 50, 50); /* 移动父对象。子对象会随之移动。 */
(为简单起见,示例中未显示对象颜色调整的代码。)
Visibility only on the parent(仅在父对象上可见)
显示原文
If a child is partially or fully outside its parent then the parts outside will not be visible.
lv_obj_set_x(obj1, -30); /*Move the child a little bit off the parent*/
This behavior can be overwritten with lv_obj_add_flag(obj, LV_OBJ_FLAG_OVERFLOW_VISIBLE) which allow the children to be drawn out of the parent.
如果一个子对象部分或完全超出父对象,则超出部分将不可见。
lv_obj_set_x(obj1, -30); /*将子对象移出父对象一点点*/
可以通过这个方法覆盖此行为 lv_obj_add_flag(obj, LV_OBJ_FLAG_OVERFLOW_VISIBLE),这会允许子对象在父对象之外进行绘制。
Create and delete objects(创建和删除对象)
显示原文
In LVGL, objects can be created and deleted dynamically at run time. It means only the currently created (existing) objects consume RAM.
This allows for the creation of a screen just when a button is clicked to open it, and for deletion of screens when a new screen is loaded.
UIs can be created based on the current environment of the device. For example one can create meters, charts, bars and sliders based on the currently attached sensors.
Every widget has its own create function with a prototype like this:
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <other parameters if any>);
Typically, the create functions only have a parent parameter telling them on which object to create the new widget.
The return value is a pointer to the created object with lv_obj_t
*
type.
There is a common delete function for all object types. It deletes the object and all of its children.
void lv_obj_delete(lv_obj_t * obj);
lv_obj_delete()
will delete the object immediately. If for any reason you
can't delete the object immediately you can use
lv_obj_delete_async(obj) which will perform the deletion on the next
call of lv_timer_handler()
. This is useful e.g. if you want to
delete the parent of an object in the child's LV_EVENT_DELETE
handler.
You can remove all the children of an object (but not the object itself) using lv_obj_clean(obj).
You can use lv_obj_delete_delayed(obj, 1000) to delete an object after some time. The delay is expressed in milliseconds.
Sometimes you're not sure whether an object was deleted and you need some way to
check if it's still "alive". Anytime before the object is deleted, you can use
cpp:expr:lv_obj_null_on_delete(&obj) to cause your object pointer to be set to NULL
when the object is deleted.
Make sure the pointer variable itself stays valid until the object is deleted. Here is an example:
在LVGL中,可以在运行时动态创建或删除对象。这也就是说,知道当对象被创建之后(存在)才会消耗内存资源。
这允许在点击按钮打开新界面(屏幕)时才创建一个新界面(屏幕),并在加载新界面(屏幕)时删除旧界面(屏幕)。
UI可以根据设备的当前环境进行创建。例如,可以根据当前连接的传感器创建仪表、图表、条形图和滑块所需的UI再进行创建(比如之前需要图标,突然传感器去掉了,那么可以选择不创建该ui控件)。
每个控件都有自己的 create 函数,函数原型如下:
lv_obj_t * lv_<widget>_create(lv_obj_t * parent, <如果有其他参数>);
通常,创建函数只有一个 parent 参数,告诉它们在哪个对象上创建新的控件。
返回值是指向创建出来的控件的指针,类型为 lv_obj_t
*
。
有一个通用的 delete 函数适用于所有对象类型。它删除对象及其所有子对象。
void lv_obj_delete(lv_obj_t * obj);
lv_obj_del()
会立即删除对象。如果出于任何原因无法立即删除对象,可以使用
lv_obj_delete_async(obj) ,它会在下一次调用 lv_timer_handler()
时执行删除操作。
这在子对象的 LV_EVENT_DELETE
处理程序中删除父对象时很有用(现在不能马上删除父对象,下一次运行lv_timer_handler时再删除)。
可以使用 lv_obj_clean(obj) 删除对象的所有子对象(但不包括对象本身)。
可以使用 lv_obj_delete_delayed(obj, 1000) 在经过一定时间后再删除对象,以毫秒为单位。
有时候,您可能不确定一个对象是否已被删除,并且需要某种方法来检查它是否仍然“存活”。在对象被删除之前,您可以随时使用:expr:lv_obj_null_on_delete(&obj) 来设置,以便在对象被删除时,您的对象指针会被设置为 NULL
。
确保指针变量本身在对象被删除之前保持有效。以下是一个示例:
Screens(屏幕)
Create screens(创建屏幕)
显示原文
The screens are special objects which have no parent object. So they can be created like:
lv_obj_t * scr1 = lv_obj_create(NULL);
Screens can be created with any object type. For example, a Base object or an image to make a wallpaper.
屏幕是一种特殊的对象,它们没有父对象。因此可以像这样创建屏幕:
lv_obj_t * scr1 = lv_obj_create(NULL);
屏幕可以使用任何对象类型创建。例如,可以使用 Base object 或者图像控件来创建壁纸。
Get the active screen(获取活动屏幕)
显示原文
There is always an active screen on each display. By default, the library creates and loads a "Base object" as a screen for each display.
To get the currently active screen use the lv_screen_active()
function.
每个显示器上都会始终存在一个活动屏幕。默认情况下,库会为每个显示器创建和加载一个“Base object”作为屏幕。
要获得当前活动的屏幕,请使用 lv_screen_active()
函数。
Load screens(加载屏幕)
显示原文
To load a new screen, use lv_screen_load(scr1).
使用 lv_screen_load(scr1) 来加载新的屏幕。
Layers(层)
显示原文
Use:cpp:expr:lv_screen_load(scr1) to load the new screen. There are two automatically generated layers:
top layer
system layer
They are independent of the screens and they will be shown on every
screen. The top layer is above every object on the screen and the
system layer is above the top layer. You can add any pop-up windows
to the top layer freely. But, the system layer is restricted to
system-level things (e.g. mouse cursor will be placed there with
lv_indev_set_cursor()
).
The lv_layer_top()
and lv_layer_sys()
functions return pointers
to the top and system layers respectively.
Read the Layer overview section to learn more about layers.
使用 lv_screen_load(scr1) 来加载新的屏幕。 自动生成两个图层:
顶层(top layer)
系统层(system layer)
它们独立于屏幕,将显示在每个屏幕上。 顶层 位于屏幕上每个对象之上, 系统层 位于 顶层 之上。您可以自由地向 顶层 添加任何弹出窗口。但是, 系统层 受到系统级别的限制(例如,鼠标光标将与 lv_indev_set_cursor()
一起放置在那里)。
层级: * 活动屏幕(screen_active) < 顶层(top layer) < 系统层(system layer) *
lv_layer_top()
和 lv_layer_sys()
函数返回指向顶层和系统层的指针。
阅读 Layer overview 章节内容,以了解更多关于图层的信息。
Load screen with animation(用动画加载屏幕)
显示原文
A new screen can be loaded with animation by using lv_screen_load_anim(scr, transition_type, time, delay, auto_del). The following transition types exist:
LV_SCR_LOAD_ANIM_NONE
: Switch immediately afterdelay
millisecondsLV_SCR_LOAD_ANIM_OVER_LEFT
,LV_SCR_LOAD_ANIM_OVER_RIGHT
,LV_SCR_LOAD_ANIM_OVER_TOP
andLV_SCR_LOAD_ANIM_OVER_BOTTOM
: Move the new screen over the current towards the given directionLV_SCR_LOAD_ANIM_OUT_LEFT
,LV_SCR_LOAD_ANIM_OUT_RIGHT
,LV_SCR_LOAD_ANIM_OUT_TOP
andLV_SCR_LOAD_ANIM_OUT_BOTTOM
: Move out the old screen over the current towards the given directionLV_SCR_LOAD_ANIM_MOVE_LEFT
,LV_SCR_LOAD_ANIM_MOVE_RIGHT
,LV_SCR_LOAD_ANIM_MOVE_TOP
andLV_SCR_LOAD_ANIM_MOVE_BOTTOM
: Move both the current and new screens towards the given directionLV_SCR_LOAD_ANIM_FADE_IN
andLV_SCR_LOAD_ANIM_FADE_OUT
: Fade the new screen over the old screen, or vice versa
Setting auto_del
to true
will automatically delete the old
screen when the animation is finished.
The new screen will become active (returned by lv_screen_active()
) when
the animation starts after delay
time. All inputs are disabled
during the screen animation.
可以使用 lv_screen_load_anim(scr, transition_type, time, delay, auto_del) 来加载一个带动画效果的新屏幕。可以设置以下动画过渡类型:
LV_SCR_LOAD_ANIM_NONE
: 在delay
毫秒后立即切换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_OUT_LEFT
,LV_SCR_LOAD_ANIM_OUT_RIGHT
,LV_SCR_LOAD_ANIM_OUT_TOP
和LV_SCR_LOAD_ANIM_OUT_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_IN
和LV_SCR_LOAD_ANIM_FADE_OUT
:将新屏幕渐变到旧屏幕上,或反之亦然
将 auto_del
设置为 true
将在动画完成后自动删除旧屏幕。
新屏幕将在 delay
时间后动画开始时变为活动状态(由 lv_screen_active()
返回)。在屏幕动画期间,所有输入都将被禁用。
Handling multiple displays(处理多个显示器)
显示原文
Screens are created on the currently selected default display. The
default display is the last registered display with
lv_display_create()
. You can also explicitly select a new default
display using lv_display_set_default(disp).
lv_screen_active()
, lv_screen_load()
and lv_screen_load_anim()
operate
on the default display.
Visit Multiple display support(多显示器支持) to learn more.
屏幕是在当前选定的 默认显示器 上创建的。 默认显示器 是最后使用 lv_display_create()
注册的显示器。您还可以使用 lv_display_set_default(disp) 显式地选择新的默认显示器。
lv_screen_active()
,lv_screen_load()
和 lv_screen_load_anim()
操作默认显示器。
请阅读 Multiple display support(多显示器支持) 章节内容,以了解更多关于多个显示器的信息。
Parts(部分)
显示原文
The widgets are built from multiple parts. For example a Base object uses the main and scrollbar parts but a Slider uses the main, indicator and knob parts. Parts are similar to pseudo-elements in CSS.
The following predefined parts exist in LVGL:
LV_PART_MAIN
: A background like rectangleLV_PART_SCROLLBAR
: The scrollbar(s)LV_PART_INDICATOR
: Indicator, e.g. for slider, bar, switch, or the tick box of the checkboxLV_PART_KNOB
: Like a handle to grab to adjust the valueLV_PART_SELECTED
: Indicate the currently selected option or sectionLV_PART_ITEMS
: Used if the widget has multiple similar elements (e.g. table cells)LV_PART_CURSOR
: Mark a specific place e.g. text area's or chart's cursorLV_PART_CUSTOM_FIRST
: Custom parts can be added from here.
The main purpose of parts is to allow styling the "components" of the widgets. They are described in more detail in the Style overview section.
部件嵌入式由多个控件组成。例如,一个 Base object 使用主要部分和滚动条部分,而一个 Slider 使用主要部分、指示器部分和旋钮部分。部件类似于CSS中的 伪元素。
LVGL中存在以下预定义的部分:
LV_PART_MAIN
:类似矩形的背景LV_PART_SCROLLBAR
:滚动条(一个或多个)LV_PART_INDICATOR
:指示器,例如滑块、条形图、开关或复选框的勾选框LV_PART_KNOB
:类似于把手(旋钮),用于调整值LV_PART_SELECTED
:指示当前选定的选项或部分LV_PART_ITEMS
:如果部件有多个类似的元素(例如表格单元格)则可用LV_PART_CURSOR
:标记特定位置,例如文本区域或图表的光标LV_PART_CUSTOM_FIRST
:可以从这里添加自定义部分。
部件的主要目的是允许对控件的 "组件(组成部分)" 进行样式设置。在 Style overview 章节中有对它们进行了更详细的说明。
States(状态)
显示原文
The object can be in a combination of the following states:
LV_STATE_DEFAULT
: Normal, released stateLV_STATE_CHECKED
: Toggled or checked stateLV_STATE_FOCUSED
: Focused via keypad or encoder or clicked via touchpad/mouseLV_STATE_FOCUS_KEY
: Focused via keypad or encoder but not via touchpad/mouseLV_STATE_EDITED
: Edit by an encoderLV_STATE_HOVERED
: Hovered by mouse (not supported now)LV_STATE_PRESSED
: Being pressedLV_STATE_SCROLLED
: Being scrolledLV_STATE_DISABLED
: Disabled stateLV_STATE_USER_1
: Custom stateLV_STATE_USER_2
: Custom stateLV_STATE_USER_3
: Custom stateLV_STATE_USER_4
: Custom state
The states are usually automatically changed by the library as the user
interacts with an object (presses, releases, focuses, etc.). However,
the states can be changed manually too. To set or clear given state (but
leave the other states untouched) use
lv_obj_add/remove_state(obj, LV_STATE_...)
In both cases OR-ed state
values can be used as well. E.g.
lv_obj_add_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED).
To learn more about the states read the related section of the Style overview.
控件可以处于以下状态的组合:
LV_STATE_DEFAULT
:正常释放状态LV_STATE_CHECKED
:切换或选中状态LV_STATE_FOCUSED
:通过键盘或编码器聚焦或通过触摸板/鼠标点击LV_STATE_FOCUS_KEY
:通过键盘或编码器聚焦但不通过触摸板/鼠标点击LV_STATE_EDITED
:由编码器编辑LV_STATE_HOVERED
:由鼠标悬停(目前不支持)LV_STATE_PRESSED
:正在按下LV_STATE_SCROLLED
:正在滚动LV_STATE_DISABLED
:禁用状态LV_STATE_USER_1
:自定义状态LV_STATE_USER_2
:自定义状态LV_STATE_USER_3
:自定义状态LV_STATE_USER_4
:自定义状态
通常情况下,LVGL库会根据用户与对象的交互(按下、释放、聚焦等)自动更改状态。然而,状态也可以用户手动进行更改。
要设置或清除给定的状态(但保持其他状态不变),可以使用 lv_obj_add/remove_state(obj, LV_STATE_...)
。
在这两种情况下,也可以使用按位或运算符来组合状态值。例如: lv_obj_add_state(obj, part, LV_STATE_PRESSED | LV_PRESSED_CHECKED)
。
要了解更多关于状态的内容,请阅读 Style overview 章节中的相关内容。
Snapshot(快照)
显示原文
A snapshot image can be generated for an object together with its children. Check details in Snapshot(快照).
一个对象和其子对象的快照图像可以一起生成。在 Snapshot(快照) 中查看详情。