显示(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 中接收的缓冲区也转移到另一个显示器。

分割影像

可以从较小的显示创建较大的显示。可以如下创建它:

  1. 将显示器的分辨率设置为大显示器的分辨率。

  2. 在中 drv.flush_cb ,截断并修改 area 每个显示的参数。

  3. 将缓冲区的内容发送到带有截断区域的每个显示。

屏幕

每个显示器都有每组屏幕和屏幕上的对象。

确保不要混淆显示和屏幕:

  • 显示 是绘制像素的物理硬件。

  • 屏幕 是与特定显示器关联的高级根对象。一个显示器可以具有与其关联的多个屏幕,但反之则不然。

屏幕可以视为没有父级的最高级别的容器。屏幕的大小始终等于其显示,屏幕的大小始终为(0;0)。 因此,无法更改屏幕坐标,即,不能在屏幕上使用 lv_obj_set_pos(), lv_obj_set_size() 或类似功能。

可以从任何对象类型创建屏幕,但是,两种最典型的类型是 `基础对象`_`图像`_ (用于创建墙纸)。

要创建屏幕,请使用 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) 。如果 dispNULL ,则将使用默认屏幕(并非所有显示)。

背景

每个显示都有背景色,背景图像和背景不透明度属性。当当前屏幕是透明的或未定位为覆盖整个显示器时,它们将变为可见。

背景色是填充显示的一种简单颜色。可以使用 ``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_tuint16_tuint32_t 根据颜色深度设置。用于从纯数字构建颜色阵列。

  • lv_opa_t 一种简单的 uint8_t 类型,用于描述不透明度。

lv_color_tlv_color1_tlv_color8_tlv_color16_tlv_color32_t 类型具有四个字段:

  • ch.red 红色通道

  • ch.green 绿色通道

  • ch.blue 蓝色通道

  • full 红+绿+蓝为一个数字

通过将 LV_COLOR_DEPTH 定义设置为1(单色),8、16或32,可以在lv_conf.h中设置当前颜色深度。

转换颜色

可以将一种颜色从当前颜色深度转换为另一种颜色。转换器函数以数字返回,因此必须使用 完整 字段:

 1    lv_color_t c;
 2    c.red   = 0x38;
 3    c.green = 0x70;
 4    c.blue  = 0xCC;
 5
 6    lv_color1_t c1;
 7    c1.full = lv_color_to1(c);      /*Return 1 for light colors, 0 for dark colors*/
 8
 9    lv_color8_t c8;
10    c8.full = lv_color_to8(c);      /*Give a 8 bit number with the converted color*/
11
12    lv_color16_t c16;
13    c16.full = lv_color_to16(c); /*Give a 16 bit number with the converted color*/
14
15    lv_color32_t c24;
16    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 (全白)。

相关API

TODO