显示(Displays),LVGL中显示的基本概念在 显示接口 部分中进行了说明。因此,在进一步阅读之前,请先阅读 显示接口 部分。
多种显示支持
在LVGL中,可以有多个显示,每个显示都有自己的驱动程序和对象。唯一的限制是,每个显示器都必须具有相同的色深(如中所述 LV_COLOR_DEPTH
)。如果在这方面显示有所不同,则可以在驱动程序中将渲染的图像转换为正确的格式 flush_cb
。
创建更多的显示很容易:只需初始化更多的显示缓冲区并为每个显示注册另一个驱动程序。创建UI时,用于 lv_disp_set_default(disp)
告诉库在其上创建对象的显示。
为什么要多显示器支持?这里有些例子:
- 具有带有本地UI的“常规” TFT显示屏,并根据需要在VNC上创建“虚拟”屏幕。(需要添加 VNC 驱动程序)。
- 具有大型TFT显示屏和小型单色显示屏。
- 在大型仪器或技术中具有一些较小且简单的显示器。
- 有两个大型TFT显示屏:一个用于客户,一个用于店员。
仅使用一个显示器
使用更多显示器可能很有用,但在大多数情况下,并非必需。因此,如果仅注册一个显示器,则整个多显示器概念将被完全隐藏。默认情况下,最后创建的(唯一的)显示用作默认设置。
lv_scr_act()
, lv_scr_load(scr)
, lv_layer_top()
, lv_layer_sys()
, LV_HOR_RES
以及 LV_VER_RES
始终应用在最后创建的(默认)屏幕上。 如果将 NULL
作为 disp
参数传递给显示相关功能,通常将使用默认显示。 例如。 lv_disp_trig_activity(NULL)
将在默认屏幕上触发用户活动。(请参见下面的非活动状态)。
镜面展示
要将显示器的图像镜像到另一台显示器,则无需使用多显示器支持。只需将在 drv.flush_cb
中接收的缓冲区也转移到另一个显示器。
分割影像
可以从较小的显示创建较大的显示。可以如下创建它:
- 将显示器的分辨率设置为大显示器的分辨率。
- 在中
drv.flush_cb
,截断并修改area
每个显示的参数。 - 将缓冲区的内容发送到带有截断区域的每个显示。
屏幕
每个显示器都有每组屏幕和屏幕上的对象。
确保不要混淆显示和屏幕:
- 显示 是绘制像素的物理硬件。
- 屏幕 是与特定显示器关联的高级根对象。一个显示器可以具有与其关联的多个屏幕,但反之则不然。
屏幕可以视为没有父级的最高级别的容器。屏幕的大小始终等于其显示,屏幕的大小始终为(0;0)。 因此,无法更改屏幕坐标,即,不能在屏幕上使用 lv_obj_set_pos(), lv_obj_set_size() 或类似功能。
可以从任何对象类型创建屏幕,但是,两种最典型的类型是 MARKDOWN_HASHc20087ee0e2941202e678e98a9203e66MARKDOWNHASH
和 MARKDOWN_HASHe1b7cee794666669f55acead93513971MARKDOWNHASH
(用于创建墙纸)。
要创建屏幕,请使用 lv_obj_t * scr = lv_<type>_create(NULL, copy)
。复制可以是另一个屏幕来复制它。
要加载屏幕,请使用 lv_scr_load(scr)
。要获取活动屏幕,请使用 lv_scr_act()
。这些功能在默认显示屏上起作用。如果要指定要处理的显示器,请使用 lv_disp_get_scr_act(disp)
和 lv_disp_load_sc(disp,scr)
。屏幕也可以加载动画。在这里阅读更多。
可以使用lv_obj_del(scr)
删除屏幕,但请确保不删除当前加载的屏幕。
透明屏幕
通常,屏幕的不透明度是 LV_OPA_COVER
为其子级提供坚实的背景。如果不是这种情况(不透明度<100%),则显示器的背景颜色或图像将可见。有关更多详细信息,请参见显示背景部分。如果显示器的背景不透明性也不是,则 LV_OPA_COVERLVGL
不会绘制纯色背景。
此配置(透明屏幕和显示器)可用于创建OSD菜单,例如在其中将视频播放到下层,并在上层创建菜单。
为了处理透明显示器,LVGL需要使用特殊(较慢)的颜色混合算法,因此需要使用LV_COLOR_SCREEN_TRANSPn 启用此功能lv_conf.h。由于此模式在像素的Alpha通道上运行,因此也是必需的。32位颜色的Alpha通道在没有对象的情况下将为0,在有实体对象的情况下将为255。LV_COLOR_DEPTH = 32
总而言之,要启用透明屏幕和显示以创建类似于OSD菜单的UI:
- 在
lv_conf.h
中启用LV_COLOR_SCREEN_TRANSP
- 请务必使用
LV_COLOR_DEPTH 32
- 将屏幕的不透明度设置为
LV_OPA_TRANSP
例如lv_obj_set_style_local_bg_opa(lv_scr_act(), LV_OBJMASK_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP)
- 使用
lv_disp_set_bg_opa(NULL, LV_OPA_TRANSP);
将显示不透明度设置为LV_OPA_TRANSP
显示器功能
不活跃
在每个显示器上测量用户的不活动状态。每次使用输入设备(如果与显示器关联)都被视为一项活动。要获取自上一次活动以来经过的时间,请使用 lv_disp_get_inactive_time(disp)
。如果传递了 NULL
,则所有显示(不是默认显示)将返回整体最小的不活动时间。
可以使用手动触发活动 lv_disp_trig_activity(disp)
。如果 disp
为 NULL
,则将使用默认屏幕(并非所有显示)。
背景
每个显示都有背景色,背景图像和背景不透明度属性。当当前屏幕是透明的或未定位为覆盖整个显示器时,它们将变为可见。
背景色是填充显示的一种简单颜色。可以使用 lv_disp_set_bg_color(disp,color)
进行调整;
背景图像是用作墙纸的文件路径或指向 lv_img_dsc_t
变量(转换后的图像)的指针。可以使用 lv_disp_set_bg_color(disp,&my_img);
进行设置。如果设置了背景图片(非 NULL
),则背景将不会填充 bg_color
。
可以使用 lv_disp_set_bg_opa(disp,opa)
调整背景颜色或图像的不透明度。
这些函数的
,以将其引用到默认显示。 disp
参数可以为
NULL
色彩
颜色模块处理所有与颜色相关的功能,例如更改颜色深度,从十六进制代码创建颜色,在颜色深度之间转换,混合颜色等。
颜色模块定义了以下变量类型:
- lv_color1_t 存储单色。为了兼容性,它也具有R,G,B字段,但它们始终是相同的值(1个字节)
- lv_color8_t 用于存储8位颜色(1字节)的R(3位),G(3位),B(2位)的结构体。
- lv_color16_t 用于存储16位颜色(2字节)的R(5位),G(6位),B(5位)的结构体。
- lv_color32_t 用于存储24位颜色(4字节)的R(8位),G(8位),B(8位)的结构体。
- lv_color_t 等于
lv_color1/8/16/24_t
根据颜色深度设置 - lv_color_int_t
uint8_t
,uint16_t
或uint32_t
根据颜色深度设置。用于从纯数字构建颜色阵列。 - lv_opa_t 一种简单的
uint8_t
类型,用于描述不透明度。
lv_color_t
, lv_color1_t
, lv_color8_t
, lv_color16_t
和 lv_color32_t
类型具有四个字段:
- ch.red 红色通道
- ch.green 绿色通道
- ch.blue 蓝色通道
- full 红+绿+蓝为一个数字
通过将 LV_COLOR_DEPTH
定义设置为1(单色),8、16或32,可以在lv_conf.h中设置当前颜色深度。
转换颜色
可以将一种颜色从当前颜色深度转换为另一种颜色。转换器函数以数字返回,因此必须使用 完整
字段:
lv_color_t c;
c.red = 0x38;
c.green = 0x70;
c.blue = 0xCC;
lv_color1_t c1;
c1.full = lv_color_to1(c); /*Return 1 for light colors, 0 for dark colors*/
lv_color8_t c8;
c8.full = lv_color_to8(c); /*Give a 8 bit number with the converted color*/
lv_color16_t c16;
c16.full = lv_color_to16(c); /*Give a 16 bit number with the converted color*/
lv_color32_t c24;
c32.full = lv_color_to32(c); /*Give a 32 bit number with the converted color*/
交换16种颜色
可以在lv_conf.h中设置 LV_COLOR_16_SWAP
以交换RGB565颜色的字节。如果通过SPI等面向字节的接口发送16位颜色,则很有用。
由于16位数字以Little Endian格式存储(低位地址的低位字节),因此接口将首先发送低位字节。但是,显示通常首先需要较高的字节。字节顺序不匹配会导致色彩严重失真。
创建和混合颜色
可以使用LV_COLOR_MAKE宏以当前颜色深度创建颜色。它使用3个参数(红色,绿色,蓝色)作为8位数字。例如,创建浅红色: my_color = COLOR_MAKE(0xFF,0x80,0x80)
.
颜色也可以从十六进制代码创建: my_color = lv_color_hex(0x288ACF)
或 my_color = lv_folro_hex3(0x28C)
.
可以混合两种颜色:mixed_color = lv_color_mix(color1, color2, ratio)
。比例可以是 0..255。 0 表示全彩色 2,255 表示全彩色 1。
也可以使用 lv_color_hsv_to_rgb(hue,saturation,value)
从HSV空间创建颜色。色相应在 0..360 范围内,饱和度和值应在 0..100 范围内。
不透明度
为了描述不透明度,创建了 lv_opa_t
类型作为 uint8_t
的包装。还介绍了一些定义:
- LV_OPA_TRANSP 值:0,表示不透明度使颜色完全透明
- LV_OPA_10 值:25,表示颜色仅覆盖一点
- LV_OPA_20 … OPA_80 比较常用
- LV_OPA_90 值:229,表示几乎完全覆盖的颜色
- LV_OPA_COVER 值:255,表示颜色完全覆盖
还可以将 LV_OPA_*
定义 lv_color_mix()
作为比率使用。
内置颜色
颜色模块定义了最基本的颜色,例如:
- #FFFFFF LV_COLOR_WHITE
- #000000 LV_COLOR_BLACK
- #808080 LV_COLOR_GRAY
- #c0c0c0 LV_COLOR_SILVER
- #ff0000 LV_COLOR_RED
- #800000 LV_COLOR_MAROON
- #00ff00 LV_COLOR_LIME
- #008000 LV_COLOR_GREEN
- #808000 LV_COLOR_OLIVE
- #0000ff LV_COLOR_BLUE
- #000080 LV_COLOR_NAVY
- #008080 LV_COLOR_TEAL
- #00ffff LV_COLOR_CYAN
- #00ffff LV_COLOR_AQUA
- #800080 LV_COLOR_PURPLE
- #ff00ff LV_COLOR_MAGENTA
- #ffa500 LV_COLOR_ORANGE
- #ffff00 LV_COLOR_YELLOW
以及 LV_COLOR_WHITE
(全白)。