基于T5平台(SMP)GUI开发
1.应用配置图形化选择
为了方便用户在固件编译阶段仅编译选产品相关的应用与指定的LVGL版本,支持通过图形化选择来配置相关应用。
首次进入图形化配置界面前执行命令行 <code data-type="tag" style="color:#e9e9e9">./build_app.sh apps/T5_gui_demo_quickstart T5_gui_demo_quickstart 1.0.0 clean</code> ,然后输入命令行 <code data-type="tag" style="color:#e9e9e9">make app_menuconfig APP_NAME=T5_gui_demo_quickstart</code> ,"T5_gui_demo_quickstart“为应用名称,1.0.0为版本号,用户可修改为自己的应用名称,进入以下图形界面。
1.1CPU框架选择
- tuya module type:配置使用的模组,可选择T5或者T2模组。
- enable cpu smp architecture:配置SMP结构,当前SDK为SMP结构,此功能必须打开。
1.2LVGL版本选择
- lvgl option:配置LVGL版本、LVGL线程优先级和栈大小等相关设置

1.设置lvgl的版本,目前支持8和9的版本
2.设置lvgl线程和绘图线程的优先级和栈空间的大小,可直接使用默认配置。
3.根据数据传输协议的字节顺序进行颜色交换,确保数据格式于LCD要求的格式一致。
4.设置SPI线程优先级,可使用默认配置。

5.配置ARM_2D图形处理库

6.设置开启LVGL库对TE信号的处理支持,主要用于LVGL 通过相应的信号和回调机制处理优化撕裂问题,需配合LCD的刷新率一起调试

7.在lvgl中开启dma2d用于图形和图像处理任务
8.在enable lvgl with dma2d已开启的前提下,DMA硬件打开复用模式可以给多个用途使用,比如LVGL刷屏和摄像头,避免同时抢占

1.3 功能组件选择
enable TUYA_UI:打开UI功能将启动涂鸦UI演示代码
enable TUYA_UIDP_CONVERT:打开UI控件和DP联动能力,实现DP上报和下发通知
enable LingDong-GUI:配置后可以使用灵动GUI绘制UI页面
enable image directly refreshes to screen:支持图片直接刷屏功能,不使用LVGL;<span style="color:#F5222D">直接刷屏的图片长宽需要和屏幕物理长宽保持完全一致</span><span style="color:#172b4d">。x配置SMP结构后才能使用此功能</span>

enable file system:此配置支持用户使用littlefs和fatfs文件系统,使用flash和SD存储文件系统资源需打开。
enable ai app component:AI功能配置,支持音频功能,使用AI对话应用时需要打开此配置。
enable libjpeg_turbo app component、enable lib-freetype app componet:打开此配置后支持使用Tuya组件解码库,与原厂的解码库解耦,可选功能;不打开则默认使用原厂解码库。

1.4图形应用选择
gui application:选择应用示例,可根据需要可选择不同的Tuya提供的应用demo或使用用户自己的应用。

tuya_ai_demo:AI玩具对话应用使用AI玩具应用时enable ai app component会强制同步打开;<span style="color:#F5222D">使用AI功能需要选择V8版本的LVGL。</span>
tuya_basic_demo:图像基本功能应用,包括基本组件、图像显示等
tuya_img_direct_flush_demo:图像刷屏演示应用,可以使用整张图片直接刷屏显示。使用时会同步强制打开image directly refreshes to screen配置。
tuya_tileview_demo:tileview拼接平铺视图控件应用示例,展示不同视图滑动切换效果。
user_gui_app:用户自己创建的应用,默认是没有这个目录的。用户需要自己创建应用并且文件名固定为user_gui_app并放置在src/gui目录下。

1.5硬件配置选择
硬件配置主要包括两个方面,UI屏幕配置与AI硬件配置,两者是互斥的。根据选择的应用示例不同,配置不同的硬件:
1.UI屏幕配置:除了选择使用tuya_ai_demo外的其他demo都需要用户自行选择屏幕相关硬件配置
TUYA LCD Screen Options:屏幕配置,根据模组的不同选择对应的屏幕接口类型,板子型号以及屏幕IC驱动,用户也可参照Tuya提供的相关驱动文件增加新的驱动。

2.AI相关配置:gui application中选择tuya_ai_demo才需要配置相关硬件,具体配置请参考WUKONG_AI配置


1.6生成配置文件
配置完成后保存当前配置,退出图形化配置界面,然后运行 <code data-type="tag" style="color:#e9e9e9">make app_config APP_NAME=T5_gui_demo_quickstart</code> ,T5_gui_demo_quickstart是项目名称,生成新的include/tuya_app_config.h文件,<span style="color:#F5222D">每次修改配置前都要执行一次清除命令</span> <code data-type="tag" style="color:#e9e9e9">./build_app.sh apps/T5_gui_demo_quickstart T5_gui_demo_quickstart 1.0.0 clean</code> ,否则修改无效。
2.系统资源(littlefs格式)
2.1首次使用外挂FLASH
- 开发板首次使用时,板载的外挂flash挂载失败会导致屏幕无法点亮,需要在日志命令行手动执行以下操作后重启:
首先执行擦除外部flash: xqspi fce\r\n
然后格式化外部flash:lfs mkfs\r\n
2.2FLASH文件系统
- 点亮后由于flash中文件系统为空,所以屏幕没有相关图片及文字展示,需要按照以下方法生成镜像文件系统。
- 目前资源文件系统统一使用littlefs格式,位于片内或者片外flash。
2.1.1镜像文件获取
1.在项目名称\\tuyaos_iot_t5_gui_demo_product_classT5_gui_demo_quickstart\\sr\\gui\\project_resource_sample
\\fs_package\\littlefs下有一个系统资源例程,fs文件夹是要打包的文件系统内容(注意:所有的资源文件名长度,包含扩展名<32个字符),将要打包的内容按照文件夹的目录树结构方式存放到里面,目录树结构如下:

4.片外flash文件系统生成执行命令:
<code>./mklittlefs -c fs/ -b xxx -p xxx -s xxx fs.bin</code>
以上参数-b -p -s请根据实际使用的flash规则参数确定,工具参数定义如下,执行完成后将fs.bin烧录至qspi-flash:
-b 块大小,默认4096
-p 页面大小,默认256
-c 输入的素材文件夹
-s 输出镜像大小,不能小于实际素材大小
-fs.bin 输出的镜像文件名称
5.片外flash的烧录要把flash单独拆卸下来通过烧录座进行烧录。
6.文件系统可存储在片外flash中和SD卡中,根据系统文件存储的位置不同,要同步修改apps/T5_gui_demo_quickstart/src/tuya_app_main.c中tuya_gui_start函数设置的文件系统所在分区。

2.2.2语言
- 多语言配置会消耗较大内存资源,如果产品应用只有一种语言,建议不要使用以下配置而使用静态字库方式
- data_file:all文件夹中保存gui中所使用的的语言文本定义,json文件命名可由用户自定义,格式请严格按照json例程中的格式来组织,如

font:该文件夹保存字体库(目前仅支持ttf字体库),请使用授权的正版字体库,否则系统字体解析会出现异常。使用时,该字体库的名称(除后缀.ttf外)一定要保持与上述语言文件夹中的字库名一致。
使用:如lv_label_set_text(language_label, tuya_app_gui_display_text_get("language_test"));
表示对象language_label使用文本标签"language_test"所对应的文字信息,如果当前语言设置为中文,该language_label则会显示“共以”,若当前语言设置为英文,则会显示“ENGLISH”。
2.2.3图片
- picture:该文件夹保存gui所使用到的图片资源,支持jpg和png两种格式。为保证gui在使用过程中显示图片的流畅性建议做图片的预解码处理(这样也会导致占用过多内存)。
- 图片的命名方式:每张图片按照唯一数字ID的方式命名(从1.jpg或1.png开始,ID不能重名,依次往后增加),用户程序在需要使用的地方调用对应的图片名称。
- 如果不使用Tuya内部的解码库,系统默认使用BK原厂的图像解码库,由于原厂解码图像时是按照4字节搬运的,使用jpg图片时,16位色深图片的像素宽一定是偶数(如13842),不要使用像素为奇数的图片(如13541),用户可通过图片编辑工具将奇数的像素转化为偶数。24位色深的jpg图片,图片的像素宽一定是4的倍数,如192x192。如果不使用符合以上要求的图片系统会限制拦截解码,图片不显示。
2.2.4音乐
- music:该文件夹保存用户使用的音频资源,每首音乐按照唯一数字ID的方式命名(从1.mp3开始,ID不能重名,依次往后增加),用户程序在需要使用的地方调用对应的名称。
2.2.5资源版本信息
- version.inf:保存资源版本信息,如0.1
2.3获取资源至设备
- 在调试阶段除了直接将文件资源烧录至flash外,还可以通过上传文件到Tuya云端再下载和使用TFTP将文件资源下载至设备。云端下载的文件会覆盖flash中已烧录的系统资源,TFTP在已有的系统资源上新增文件。
2.3.1TFTP下载资源(调试阶段)
- 获取TFTP客户端: https://pjo2.github.io
- 开启设备端TFTP Serverq服务:在项目名称\\apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_app_gui_config.h中打开宏定义"TUYA_TFTP_SERVER"(<strong>量产阶段固件务必关闭此宏定义,避免出现安全问题</strong>)
- 从设备日志端获取TFTF Server ip及端口信息,如下:

- windows端打开tftp 客户端工具,按如下配置:

目前TFTP下载的文件仅支持GUI相关的几种文件格式:
语言配置文件:.json(文件名无限制)
字体库文件:.ttf(上传的文件名按照2.2.2所示)
音频文件:.mp3(上传文件名按照2.2.4所示)
图片文件:.jpg/.png/.gif(上传的文件名按照2.2.3所示)
资源信息文件(固定名称,不可改变):version.in
下载成功后可看到相关日志,以上传图片111.png为例,如下:

3.系统调试
- 日志口UART1,波特率为460800。
- 固件烧录口UART0,波特率为2000000,使用BKFIL进行烧录。
- 系统编译:带gui例程的工程名为T5_gui_demo_quickstart,使用以下命令行进行编译 <code>./build_app.sh apps/T5_gui_demo_quickstart T5_gui_demo_quickstart 1.0.0</code> ,再次编译时需要先输入清除命令 <code>./build_app.sh apps/T5_gui_demo_quickstart T5_gui_demo_quickstart 1.0.0 clean</code>
4.应用接口
4.1初始化
4.1.1GUI相关头文件
#include "tuya_app_gui_gw_core0.h"
#include "tuya_app_gui_fs_path.h"
#include "tuya_list.h"
#include "app_ipc_command.h"
#include "tkl_display.h"
#include "smart_frame.h"
#include "tal_sw_timer.h"
#include "uni_log.h"
#include "tdd_lcd.h"
#ifdef TUYA_APP_DRIVERS_TP
#include "tal_tp_service.h"
#include "tkl_lvgl_adapter.h"
#endif
#ifdef TUYA_TFTP_SERVER//调试阶段用于从局域网通过tftp客户端工具上传资源文件
#include "tuya_app_gui_tftp.h"
#endif
4.2.2入口函数
DP数据与UI具有强相关联性,设备在激活状态下执行tuya_gui_start函数前需要完成所有dp数据的初始化,否则gui侧控件展示可能会有屏幕刷新现象。
STATIC VOID tuya_gui_start(BOOL_T is_mf_test)
- 入参BOOL_T is_mf_test:是否为产测模式;
- 根据图形化界面配置的屏幕设备使用不同的屏幕及TP使用引脚初始化:
- 设置文件系统所在分区(内部flash、外部flash或外部SD卡);
OPERATE_RET tuya_app_gui_set_lfs_partiton_type(TUYA_GUI_LFS_PARTITION_TYPE_E partition_type)
- GUI系统事件处理回调注册:处理如gui侧的死机,重启,屏幕保护,语言配置及用户自定义的私有等请求;
OPERATE_RET tuya_gui_system_event_hdl_register(GUI_SYS_EVENT_CB cb)
- 用户需特殊处理的gui侧控件变换回调(组件已经帮忙处理控件对应dp的上报逻辑,如果不需要对特定控件变换进行处理,可无需注册)
OPERATE_RET tuya_gui_obj_event_hdl_register(GUI_OBJ_EVENT_CB cb)
- 用户手动初始化GUI控件状态的处理回调注册(这个注册函数提供给用户在上电时初始化控件状态,一般当设备没有被激活无法通过组件的dp自身去初始化控件的情况下使用)
OPERATE_RET tuya_gui_dp2obj_pre_init_hdl_register(GUI_DP2OBJ_PRE_INIT_EVENT_CB cb)
- GUI控件至涂鸦dp转换回调注册:用户需要根据实际应用,将gui侧控件事件数据LV_DISP_EVENT_S转换为涂鸦的dp数据DP_REPT_CB_DATA.
OPERATE_RET tuya_gui_obj2dp_convert_hdl_register(GUI_OBJ2DP_CONVERT_CB cb)
- 核心函数初始化:
VOID tuya_gui_init(BOOL_T is_mf_test, TKL_DISP_INFO_S *info, CHAR_T *weather_code)
- 如果用户对天气预报数据的内容有特殊要求,可自定义入参中的weather_code,否则为系统默认的天气数据,可参考:https://developer.tuya.com/cn/docs/mcu- ... fvzw7ny80s,如需要输出天气数据温度,最高温度,最低温度,湿度,天气概况数字编码(这里使用天气概况数字编码主要是为了适用不同国家时多语言配置,),可将入参weather_code设置为如下json数组字符串(w.date.1 :表示需要预报一天的数据,支持17天的预报,一定要包括该参数,否则后面天气数据解析会有问题,联网成功后,每半小时更新一次):
"\[\\"w.temp\\",\\"w.thigh\\",\\"w.tlow\\",\\"w.humidity\\",\\"w.conditionNum\\",\\"w.date.1\\"\]"
- tftp服务初始化:tuya_app_gui_tftp_server_init()
应用框架支持开启宏定义TUYA_TFTP_SERVER来支持本地资源(图片,语言配置及字库文件)通过tftp的方式上传至设备端,建议产品量产固件关闭该功能
4.2.3 屏幕配置
在入口函数中需要根据屏幕设备来配置不同屏幕及TP使用引脚进行初始化,用户添加自己的对应屏幕配置:
多屏幕扩展配置
目前多屏幕最多支持两个屏幕,四种扩展方式。目前开发包支持QSPI接口、SPI接口的屏幕进行扩展:

- 用户根据需要在入口函数中配置屏幕是否扩展以及扩展方式

<p>2.屏幕驱动初始化</p>
通过 <code>ty_display_cfg</code> 结构体配置屏幕接口的引脚,包括SPI引脚映射、复位引脚、电源引脚等

在函数tdd_lcd_driver_query(CONST CHAR_T *name, UINT_T type)中写入对应LCD驱动名称和类型以查询到application_drivers中的LCD驱动文件


3.TP驱动初始化
- 通过ty_tp_user_cfg_t结构体配置触摸屏的I2C接口、复位引脚、中断引脚等。

- 引用TP驱动文件中定义的设备配置,把设备配置与用户配置的tp_cfg通过Tuya接口函数 <code>tkl_lvgl_tp_handle_register</code> 注册到LVGL图形库中,实现识别并响应触摸屏输入功能和UI交互。


4.多屏幕初始化
- 当使用扩展屏时需要对第二个屏幕同样执行以上初始化过程

4.2 GUI应用
- 用户需创建自己的图形应用放置于目录\\apps\\T5_gui_demo_quickstart\\src\\gui\\user_gui_app\\下
4.2.1 GUI支持的绘图方式
NXP GUI-Guider-1.7.2(LVGL v8.3.10)(工具辅助)
将工具生成的代码目录custom&generated导入到:项目名称\\apps\\tuyaos_iot_t5_gui_demo_product_class-T5_gui_demo_quickstart\\src\\gui\\user_gui_app\\下.
在项目名称\\apps\\T5_gui_demo_quickstart\\src\\gui\\user_gui_app\\generated\\gui_duider.h中增加引用头文件
#include "tuya_app_gui.h"
在项目名称\\apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_app_gui_config.h中打开宏定义"NXP_GUI_GUIDER"(同时关闭宏定义“EEZ_STUDIO”)
EEZ Studio(0.13.1)(LVGL v8.3/LVGL v8.3 with EEZ Flow)(工具辅助)
将工具生成的代码目录src导入到:项目名称\\apps\\T5_gui_demo_quickstart\\src\\gui\\user_gui_app\\下.
在项目名称\\apps\\T5_gui_demo_quickstart\\src\\gui\\user_gui_app\\src\\ui\\ui.h中增加引用头文件:#include "tuya_app_gui.h"
在项目名称\\apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_app_gui_config.h中打开宏定义"EEZ_STUDIO"(同时关闭宏定义“NXP_GUI_GUIDER")
直接手动绘制
将手动编写的绘图c代码放置于:\\apps\\T5_gui_demo_quickstart\\src\\gui\\user_gui_app\\下
在项目名称\\apps\\T5s_gui_demo_quickstart\\src\\gui\\tuya_app_gui_config.h中同时关闭宏定义“NXP_GUI_GUIDER"及"EEZ_STUDIO"
在\\apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_app_gui_main.c中在以下红色框中增加用户自己的绘图入口函数名:

4.2.2 GUI图片预解码
- 用户可在apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_app_gui_main.c文件的tuya_app_gui_main_init函数中增加设备启动时的背景图显示与图片预加载功能,不需要时设置为NULL,预加载功能也可不实现;

- 图片放在资源文件系统,程序启动时建议做预解码,预解码实现可参考图形基本功能演示应用(apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_basic_demo\\lv_example_switch_1.c)中的函数void tuya_app_gui_img_pre_decode(void);
- 使用jpg_img_load或png_img_load做预解码时,一定要使用tuya_app_gui_get_picture_full_path获取文件的全路径(切换页面时,可调用jpg_img_unload/png_img_unload释放对应的图片数据内存,否则有内存泄漏)
- 使用img_file_load_by_id做预解码时,用户只需要指定图片id(切换页面时,可调用img_file_unload释放对应的图片数据内存,否则有内存泄漏)
- 当flash空间足够大时也可以不释放对应的图片数据内存,释放后切换回界面需要重新解码会影响图片加载速度。
4.2.3 GUI与业务交互
1. 消息通讯数据结构:
typedef struct
{
char *tag;//对象标识,具有唯一性
uint32_t obj_type;//对象类型(如switch/slider/button等)
uint32_t event;//事件(widget器件事件/系统事件)
uint32_t param;//事件内容
} LV_DISP_EVENT_S;
- 标识tag,由于GUI对象状态和业务逻辑是相关联的,当GUI对象发生改变时或业务逻辑端dp状态改变需要同步到GUI对象时,此时都会触发事件回调,那么对象需要有一个唯一在业务与GUI之间作为信息交互的身份识别标识。用户可以在添加事件回调函数前通过lv_obj_set_tag函数注册控件的标识(注意:这个标识在整个项目中一定具有唯一性),如下红色框中所示:

特别注意:如果创建一个屏幕对象,同时给该屏幕对象通过lv_obj_set_tag设置过tag,切换页面时:
通过lv_obj_clean()清除当前页面子对象,一定要手动执行lvMsgEventDel来清除当前页面的tag,如下:
Code: Select all
//创建一个新页面
lv_obj_t *switch_screen = lv_obj_create(NULL);
lv_scr_load(switch_screen);
lv_obj_set_tag(switch_screen, "sw_screen"); //配置tag
lv_obj_add_event_cb(switch_screen, switch_screen_event_handler, LV_EVENT_ALL, NULL);
//切换到其他页面
lv_obj_clean(switch_screen); //清除当前页面
void lvMsgEventDel(lv_obj_t *obj);
lvMsgEventDel(switch_screen); //特殊............屏幕tag,需要手动清除,否则下次重新切回当前屏幕tag重复后异常崩溃!
extern void ty_screen_entry_cloud_recipe_test(void); //加载新页面
ty_screen_entry_cloud_recipe_test();通过lv_obj_del()清除当前页面子对象及页面父对象时无需执行lvMsgEventDel来清除当前页面的tag。
2.LLV_EVENT_BY_DIRECT_REPORT标志
通过接口aic_lvgl_msg_event_change发送控件变化事件时,数据lvglMsg_t中的event成员是否带标志LLV_EVENT_BY_DIRECT_REPORT有如下含义:
带LLV_EVENT_BY_DIRECT_REPORT:表示控件对应的dp数据直接上报云端,不需要cp0处理任何业务逻辑;
不带LLV_EVENT_BY_DIRECT_REPORT:表示控件对应的dp数据先由cp0业务处理后,由业务逻辑自己上报.
4.3 GUI相关接口
4.3.1 DP交互相关
- dp数据变化通知注册回调:dp发生变化时处理回调函数,用户回调处理函数要区分是普通dp数据(DP_CNTL_S *)还是raw类型数据(TY_RAW_DP_REPT_S *),然后将不同的数据信息转变成对应的控件信息.
void tuya_app_gui_dp_update_notify_callback_register (gui_dp_update_cb_t cb)
- 获取指定dp的相关信息(仅在设备激活状态有效):通过指定的dpid获取相关的信息(DP_CNTL_S *), (raw类型数据信息暂不支持获取,需要数据变化时用户自己缓存)
void *tuya_app_gui_get_dp_cntl(unsigned char dpid)
4.3.2 设备状态相关
- 获取当前wifi连接状态信息:查询wifi是否连接上云端(仅当连接上时,输出的rssi及ssid为有效)
bool tuya_app_gui_is_wifi_connected(signed char *out_rssi, char *ssid_buff, int ssid_buff_size)
- 获取当前设备激活状态信息:bool tuya_app_gui_is_dev_activeted(void);
- 请求解绑当前设备接口:void tuya_app_gui_request_dev_unbind(void);
- 获取当前时间信息接口:bool tuya_app_gui_request_local_time(char *time_buff, int time_buff_size)
- 获取天气预报数据接口:查询当前天气信息(天气预报数据格式为:LKTLV),参考
https://developer.tuya.com/cn/docs/mcu- ... 1%EF%BC%89
bool tuya_app_gui_request_local_weather(char **local_weather, uint32_t *weather_len)
***注意:local_weather为输出的天气信息字符串,使用完后需要用户手动释放其指向的内存
- 请求资源更新接口:该接口会查询云端是有有新的资源可供更新;
void tuya_app_gui_query_resource_update(void)
4.3.3 配置读写相关
- 以下接口写操作均采用了异步操作,所以不支持执行写操作后立即回读;
- kv操作相关(配置保存在片内kv区域):
<p>读接口:bool tuya_app_gui_kv_common_read(char *key, unsigned char **value, uint32_t *p_len)</p>
<p>"value"所指向的内存空间需要使用者自己释放</p>
<p>写接口:bool tuya_app_gui_kv_common_write(char *key, unsigned char *value, uint32_t len)</p>
- kv文件操作相关(配置保存在flash的文件系统区域):
<p>读接口:bool tuya_app_gui_fs_kv_common_read(char *key, unsigned char **value, uint32_t *p_len);</p>
<p>"value"所指向的内存空间需要使用者自己释放</p>
<p>写接口:bool tuya_app_gui_fs_kv_common_write(char *key, unsigned char *value, uint32_t len);</p>
4.3.4 私有事件处理
- 如果已有的事件类型无法满足用户的需求,用户可以使用自定义的私有事件LLV_EVENT_USER_PRIVATE,需要定义一个处理函数:
voidtuya_app_gui_user_private_event_process(void *data);
- 定义一个私有的数据结构,交互时将指针指向lvglMsg_t中的param参数。
- 代码实现可参考apps\\T5_gui_demo_quickstart\\src\\gui\\tuya_ai_demo\\tuya_ai_display.c中的函数void tuya_app_gui_user_private_event_process(void *data);
5. 示例展示
5.1四个基本示例
- 在apps\\T5_gui_demo_quickstart\\src\\gui\\目录下有四个演示demo,分别是:
- tuya_ai_demo:AI玩具对话应用示例。
- tuya_basic_demo:图形基本功能应用示例,包括基本组件,文字使用,图形展示以及DP数据与UI交互等基础功能。
- tuya_img_direct_flush_demo:图片直接刷屏应用示例,在demo中不使用lvgl系统直接使用图片刷屏,可控制刷屏速度。
- tuya_tileview_demo:tileview拼接平铺视图控件应用示例,通过示例演示了如何创建和操控平铺视图,通过TP滑动在不同视图之间切换。
5.2 tuya_basic_demo

5.2.1 入口函数 void lv_example_switch_1
在lvgl中对象(object)是UI的基本构建单元,所有对象必须挂载在父对象上,入口函数首先创建一个基础屏幕对象
<code>switch_screen = lv_obj_create(NULL);</code>
创建对象后必须注册控件的标识以便信息交互: <code>lv_obj_set_tag(switch_screen,"sw_screen");</code> 然后可用函数设置对象的大小,颜色,位置等属性。

- 创建显示在屏幕上的子对象

- 对象属性设置常用函数
| 属性 | 函数 |
|---|---|
| 设置大小 | lv_obj_set_size(obj, w, h) |
| 设置位置 | lv_obj_set_pos(obj, x, y) |
| 设置背景颜色 | lv_obj_set_style_bg_color(obj, value, selector) |
| 设置透明度 | lv_obj_set_style_bg_opa(obj, value, selector) |
| 设置对齐方式与偏移 | lv_obj_align(obj, align, x_ofs, y_ofs |
- 在入口函数中通过 <code>lv_obj_add_event_cb</code> 函数为对象注册事件回调函数,实现用户交互响应机制,在回调函数中处理TP操作的点击、滑动、按压等相关事件。
- 当DP数据与UI有交互时需要注册DP更新事件回调函数,在回调函数中解析不同类型的DP数据更新,根据DPID执行相应的逻辑以更新UI界面。

5.2.2语言文字使用
- 在支持多语言的应用中,建议一定按照如下图步骤使用

- 先通过接口函数const void *tuya_app_gui_display_text_font_get(char *node_name),输入入参文本标签得到指定的字库信息(注意:获取不到字库信息,就不要强制再通过lv_obj_set_style_text_font函数设置字体,否则字体内容异常会导致系统崩溃)
- 然后通过接口函数const void *tuya_app_gui_display_text_get(char *node_name),输入入参文本标签得到指定的文本信息(4.1中提及)(注意:获取不到文本信息,就不要强制再通过lv_obj_set_style_text_font函数设置文本,否则文本异常会导致系统崩溃)
- 切换语言时,系统会清除之前的老的语言环境而使用新的语言环境,所以在响应语言切换的控件回调处理函数中,必须要更新页面中所有使用到字库的文字控件(如果只更新部分文字控件会导致lvgl在下一个屏幕刷新周期来到的时候,指向老的语言环境的文字控件因找不到老的语言环境而导致系统异常)
5.2.3 图片演示
1.单个图片显示
- 在预解码函数中通过图像id解码图像文件:

- 通过创建容器和图像对象实现对图片的布局与显示,并且支持预解码和即时加载两种方式获取使用的图片:

2.动态加载并显示多个图片
- void tuya_app_gui_img_pre_decode:在预加载函数中批量预加载与解码图片文件到内存中,使用链表管理多个图片节点。
- static uiImageArray_disp:函数能够动态创建并显示一组水平排列图片,并且实现图像的自适应缩放。
5.2.4 音乐播放相关接口
- tuya_app_gui_audio_file_play(char *audio_file):传入音乐文件存储路径,播放mp3音乐文件。
- tuya_app_gui_audio_volume_set(uint32_t volume):设置音乐播放声音的音量大小,音量范围0-100。
- tuya_app_gui_audio_volume_get(uint32_t *volume):获取本地音频音量。
- tuya_app_gui_audio_play_pause():音频暂停播放
- tuya_app_gui_audio_resume():音频继续播放
5.3 tuya_img_direct_flush_demo
5.3.1 获取图片资源
- 图片直接刷屏时,使用图片的长宽需要保持和屏幕物理长宽完全一致,屏幕尺寸可在屏驱文件中查看。在目录
tuyaos_iot_t5_gui_demo_product_class\\application_drivers\\tdd_lcd_driver\\src中有不同屏幕对应的屏驱文件,根据相关配置找到对应的屏驱文件,如3.5英寸RGB接口T5AI开发板:

- 在lcd_rgb_ili9488.c文件中有屏设备的配置结构体,包含屏幕宽高的相关参数,注意屏幕是横屏还是竖屏,图片的宽高不能与屏幕相反。

<p>2. 将\T5_gui_demo_quickstart\sr\gui\project_resource_sample\fs_package\littlefs\fs\t5_fs\picture中的图片替换成使用的图片然后参考2.系统资源章节中的步骤重新将文件资源烧录到flash中。</p>
5.3.2 预解码
- 存在FLASH中的JPG和PNG格式图片中不能直接刷屏,需要通过预解码将图像解码后才能刷屏显示。用户需要在 <code>tuya_app_gui_img_pre_decode</code> 函数中对图片进行预解码处理

- 以位图形式保存的图片,不用预解码处理可直接调用tuya_img_direcr_flush函数进行刷屏显示。
5.3.3 入口函数
- 图片直接刷屏功能的启动入口函数是 <code>img_direct_flush_demo_start</code> ,实现了从图片节点链表uiimginfoHead中遍历提取图片数据,通过 <code>tuya_img_direct_flush</code> 函数直接进行循环刷新显示。
- tuya_img_direct_flush函数:输入图片数据指针二维数组、图片总数和刷新间隔,可以绕过LVGL的流程直接控制显示,修改刷新间隔可控制图片刷新快慢。

5.3.4 文字显示
- 在直接刷屏模式下可进行文字信息显示,在图片直刷demo中DP点开关下发后能触发文字的显示,修改函数 <code>tuya_img_direct_flush_query_resource_update</code> 的参数可以修改文字显示的方向

- 在函数 <code>img_direct_flush_resource_dl_display</code> 中显示对应资源下载阶段的文本,在显示文本时图片循环刷新显示会暂停。

6.其他注意
6.1 烧录新的系统资源后仍然无更新问题(调试阶段)
- SDK支持双文件系统,文件系统最上层目录分别是:
- t5_fs/
- t5_fs_tmp/
- 云端下载文件存储路径会在两个目录中交替切换,固件使用的路径默认为最新文件下载的目录。当有效目录为t5_fs_tmp/时,此时用户再次向flash中烧录新的系统资源,烧录文件使用的目录固定为t5_fs/。但固件仍使用t5_fs_tmp/,所以会出现文件系统未更新的现象,日志输出的文件也保持云端下载的文件资源,。
- 如果用户需要flash中新烧录的文件,需要修改当前有效文件系统路径为flash中烧录的文件系统路径。
- tuyaos_iot_t5_gui_demo_product_class/application_components/ty_app_component_lvgl_dp2widget/src/tuya_app_gui_gw_core0.c文件中的tuya_gui_fs_init(void)函数与设置当前有效文件路径有关,需要将判断条件OPRT_OK != op_ret修改为OPRT_OK == op_ret(调试阶段使用),将固件使用的文件路径切换到t5_fs/

- 可在tuya_app_gui_fs_path_type_init(void)函数的有关日志中查看当前的有效路径
