02 exeasyui扩展库应用
作者:沈园园 | 最后修改:2026-04-09
一、概述
AirLCD_1010 是合宙推出的一款SPI接口,3.5寸屏,480*320 的LCD配件板,其中:
1、显示屏的驱动IC是:ST7796;
2、触摸部分:I2C接口+触摸中断INT信号,5点电容触摸
3、11个插针管脚:LCD_CLK LCD_SDA LCD_RST LCD_RS LCD_CS BKL I2C_SCL I2C_SDA INT VCC GND;
说明:
- INT为触摸中断信号;
- BKL:背光控制管脚,默认高电平,背光常亮;低电平时背光熄灭;
- VCC:2.8V-3.3V;
4、适用于Air780系列/Air8000系列;
二、演示功能概述
1、核心主程序模块
- main.lua - 主程序入口,负责系统初始化和任务调度
- ui_main.lua - exeasyui 主程序,负责页面管理和按键事件分发和执行exeasyui的任务调度
2、显示页面模块
- home_page.lua - 主页模块,提供应用入口和导航功能
- component_page.lua - UI 组件演示模块
- default_font_page.lua - 默认12号英文点阵字体演示模块
3、驱动模块
- hw_default_font_drv.lua - lcd显示驱动配置、tp触摸驱动配置和驱动模块,使用内置12号英文点阵字体
三、准备硬件环境

1、Air780EPM核心板 × 1
2、AirLCD_1010 触摸配件板 × 1
3、母对母杜邦线 × 14
4、TYPE-C 数据线 × 1
5、Air780EPM核心板和 AirLCD_1010配件板的硬件接线方式为:
- Air780EPM核心板通过 TYPE-C USB 口供电(核心板正面开关拨到 ON 一端),此种供电方式下,VDD_EXT 引脚为 3.3V,可以直接给 AirLCD_1010配件板供电;
- 为了演示方便,所以 Air780EPM核心板上电后直接通过 VBAT 引脚给 AirLCD_1010配件板供电;
- 客户在设计实际项目时,一般来说,需要通过一个 GPIO 来控制 LDO 给配件板供电,这样可以灵活地控制配件板的供电,可以使项目的整体功耗降到最低;
LCD 显示屏接线
| Air780EPM 核心板 | AirLCD_1010配件板 |
|---|---|
| 53/LCD_CLK | SCLK/CLK |
| 52/LCD_CS | CS |
| 49/LCD_RST | RES/RST |
| 50/LCD_SDA | SDA/MOS |
| 51/LCD_RS | DC/RS |
| 22/GPIO1 | BLK |
| VBAT | VCC |
| 67/I2C1_SCL | SCL |
| 66/I2C1_SDA | SDA |
| 19/GPIO22 | INT |
四、准备软件环境
4.1 软件环境
在开始实践本示例之前,先筹备一下软件环境:
1、烧录工具:Luatools 下载调试工具
2、本demo开发测试时使用的固件为LuatOS-SoC_V2018_Air780EPM 1号固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件Air780EPM固件,Air780EHM固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;
3、脚本文件:
Air780EPM脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EPM/demo/accessory_board/AirLCD_1010/exeasyui
Air780EHM脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EHM_Air780EHV_Air780EGH/demo/accessory_board/AirLCD_1010/exeasyui
4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件
准备好软件环境之后,接下来查看如何烧录项目文件到Air780EPM核心板,将本篇文章中演示使用的项目文件烧录到Air780EPM/Air780EHM核心板中。
4.2 API 介绍
exeasyui UI扩展库:https://docs.openluat.com/osapi/ext/exeasyui/
五、程序结构
AirLCD_1000/exeasyui/
│── hw_drv
│── hw_default_font_drv.lua
│── images
│── xxx.jpg
│── tp_key_drv
│── key_drv.lua
│── ui
│── component_page.lua
│── default_font_page.lua
│── home_page.lua
│── ui_main.lua
│── readme.md
5.1 文件说明
1、hw_drv:
- hw_default_font_drv.lua:LCD显示驱动配置驱动模块,使用内置 12 号英文点阵字体
2、images:
xxx.jpg:演示图片文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)
3、tp_key_drv:
- key_drv.lua:无触摸仅显示,通过按键方式进行UI交互的初始化方式正在开发中
5、ui
- ui_main.lua:exeasyui 主程序,负责页面管理和按键事件分发和执行exeasyui的任务调度
- home_page.lua :主页模块,提供应用入口和导航功能
- component_page.lua:UI 组件演示模块
- default_font_page.lua:默认12号英文点阵字体演示模块
六、代码详解
6.1 main.lua
主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。
6.2 hw_default_font_drv.lua
本文件为默认字体、lcd和tp驱动模块,核心业务逻辑为:
1、使用lcd内核固件中自带的12号英文点阵字体;
2、根据配置的字体、lcd和tp参数,初始化exEasyUI默认使用的字体、硬件显示和触摸;
3、提供无需外部硬件的字体显示能力;
-- 使用默认12号中文字体初始化exEasyUI硬件
ui.hw_init({
-- lcd_config参数填写可以参考合宙exlcd显示扩展库exlcd.init(param)接口说明:https://docs.openluat.com/osapi/ext/exlcd/#31-exlcdinitparam
lcd_config = {
lcd_model = "AirLCD_1010", -- LCD型号
-- pin_vcc = 24, -- 供电引脚,使用GPIO控制屏幕供电可配置
pin_rst = 36, -- 复位引脚
pin_pwr = 1, -- 背光控制引脚GPIO ID号
pin_pwm = 0, -- 背光控制引脚PWM ID号
port = lcd.HWID_0, -- 驱动端口
-- pin_dc = 0xFF, -- lcd数据/命令选择引脚GPIO ID号,使用lcd 专用 SPI 接口 lcd.HWID_0不需要填此参数,使用通用SPI接口需要赋值
direction = 0, -- lcd屏幕方向 0:0° 1:90° 2:180° 3:270°,屏幕方向和分辨率保存一致
w = 320, -- lcd 水平分辨率
h = 480, -- lcd 竖直分辨率
xoffset = 0, -- x偏移(不同屏幕ic 不同屏幕方向会有差异)
yoffset = 0, -- y偏移(不同屏幕ic 不同屏幕方向会有差异)
sleepcmd = 0X10, -- 睡眠命令,默认0X10
wakecmd = 0X11, -- 唤醒命令,默认0X11
-- bus_speed = 50*1000*1000, -- SPI总线速度,不填默认50M,若速率要求更高需要进行设置
-- interface_mode = lcd.WIRE_4_BIT_8_INTERFACE_I, -- lcd模式,默认lcd.WIRE_4_BIT_8_INTERFACE_I
-- direction0 = {0x36,0x00}, -- 0°方向的命令,(不同屏幕ic会有差异)
-- direction90 = {0x36,0x60}, -- 90°方向的命令,(不同屏幕ic会有差异)
-- direction180 ={0x36,0xc0} , -- 180°方向的命令,(不同屏幕ic会有差异)
-- direction270 = {0x36,0xA0}, -- 270°方向的命令,(不同屏幕ic会有差异)
-- hbp = nil, -- 水平后廊
-- hspw = nil, -- 水平同步脉冲宽度
-- hfp = 0, -- 水平前廊
-- vbp = 0, -- 垂直后廊
-- vspw = 0, -- 垂直同步脉冲宽度
-- vfp = 0, -- 垂直前廊
-- initcmd = nil, -- 自定义屏幕初始化命令表
-- flush_rate = nil, -- 刷新率
-- spi_dev = nil, -- spi设备,当port = "device"时有效,当port ≠ "device"时可不填或者填nil
-- init_in_service = false, -- 允许初始化在lcd service里运行,在后台初始化LCD,默认是false,Air8000/G/W/T/A、Air780EHM/EGH/EHV 支持填true,可加快初始化速度,默认SPI总线速度80M
},
-- tp_config参数填写可以参考合宙extp触摸扩展库以下三个接口说明:https://docs.openluat.com/osapi/ext/extp/#41-extpinitparam
-- 按extp.init(param)接口说明填写tp_model、i2c_id、pin_rst、pin_int参数
-- 按extp.set_publish_enabled(msg_type, enabled)接口说明和实际需求填写message_enabled{}列表内参数
-- 按extp.set_swipe_threshold(threshold)接口说明填写swipe_threshold和long_press_threshold参数
tp_config = {
tp_model = "AirLCD_1010", -- 触摸芯片/设备型号
i2c_id = 1, -- I2C总线ID
pin_rst = 0xFF, -- 触摸芯片复位引脚(AirLCD_1010上没有引出该引脚)
pin_int = 22, -- 触摸芯片中断引脚
-- @param message_enabled 消息类型 ("ALL", "RAW_DATA", "TOUCH_DOWN", "MOVE_X", "MOVE_Y", "SWIPE_LEFT", "SWIPE_RIGHT", "SWIPE_UP", "SWIPE_DOWN", "SINGLE_TAP", "LONG_PRESS")
message_enabled = {
TOUCH_DOWN = true, -- 启用按下检测
MOVE_X = true, -- 启用横向滑动
MOVE_Y = true, -- 启用纵向滑动
SWIPE_LEFT = true, -- 启用左滑手势
SWIPE_RIGHT = true, -- 启用右滑手势
SWIPE_UP = true, -- 启用上滑手势
SWIPE_DOWN = true, -- 启用下滑手势
SINGLE_TAP = true, -- 启用点击手势
LONG_PRESS = false -- 禁用长按手势
},
swipe_threshold = 10, -- 设置滑动阈值
long_press_threshold = 2000 -- 设置长按阈值(毫秒)
}
})
6.3 key_drv.lua
无触摸仅显示,通过按键方式进行UI交互的初始化方式正在开发中
-- 无触摸仅显示,通过按键方式进行UI交互的初始化方式正在开发中
6.4 ui_main.lua
本文件为exeasyui主程序模块,核心业务逻辑为:
1、设置主题为浅色;
2、进入演示主页面;
3、启用主循环;
local home_page = require("home_page")
-- 启动UI主任务
local function ui_main()
-- 初始化UI主题
ui.sw_init({ theme = "light" })
home_page.create()
-- 主渲染循环
while true do
ui.refresh()
sys.wait(30)
end
end
sys.taskInit(ui_main)
6.5 home_page.lua
本文件为主页功能模块,核心业务逻辑为:
1、创建应用主窗口并配置背景颜色;
2、配置子页面工厂函数,管理各演示页面的创建;
3、创建标题和功能按钮,提供页面导航功能;
4、处理按钮点击事件,实现页面切换;
local home_page = {}
--[[
创建主页界面;
@api home_page.create()
@summary 创建并配置应用主页面
@return nil
@usage
-- 在UI主程序中调用创建主页
home_page.create()
]]
function home_page.create()
-- 创建主页
local home = ui.window({ background_color = ui.COLOR_WHITE })
home.visible = true
-- 配置子页面工厂
home:configure_subpages({
component = function() return require("component_page").create(ui) end,
default_font = function() return require("default_font_page").create(ui) end
})
-- 标题
local title = ui.label({
x = 80,
y = 30,
text = "exEasyUI Demo System",
color = ui.COLOR_BLACK,
size = 12
})
local subtitle = ui.label({
x = 75,
y = 60,
text = "Based on exEasyUI v1.7.0",
color = ui.COLOR_GRAY,
size = 12
})
-- 组件演示按钮
local btn_component = ui.button({
x = 20,
y = 100,
w = 280,
h = 50,
text = "Component Demo",
bg_color = ui.COLOR_BLUE,
text_color = ui.COLOR_WHITE,
on_click = function()
home:show_subpage("component")
end
})
-- 默认字体演示按钮
local btn_default_font = ui.button({
x = 20,
y = 170,
w = 280,
h = 50,
text = "Default Font Demo",
bg_color = ui.COLOR_RED,
text_color = ui.COLOR_WHITE,
on_click = function()
home:show_subpage("default_font")
end
})
-- 添加所有组件到窗口
home:add(title)
home:add(subtitle)
home:add(btn_component)
home:add(btn_default_font)
ui.add(home)
end
return home_page
6.6 component_page.lua
本文件为组件演示页面功能模块,核心业务逻辑为:
1、创建带上下滚动功能的演示窗口;
2、展示进度条、消息框、按钮、复选框、输入框、下拉框、图片轮播等UI组件;
3、演示组件的交互功能和事件处理;
4、提供返回主页的导航功能;
local component_page = {}
--[[
创建组件演示页面;
@api component_page.create(ui)
@summary 创建组件演示页面界面
@table ui UI库对象
@return table 组件演示窗口对象
@usage
-- 在子页面工厂中调用创建组件演示页面
local component_page = require("component_page").create(ui)
]]
function component_page.create(ui)
local win = ui.window({
background_color = ui.COLOR_WHITE,
x = 0,
y = 0,
w = 320,
h = 480
})
-- 启用滚动
win:enable_scroll({
direction = "vertical",
content_height = 800,
threshold = 10
})
-- 标题
local title = ui.label({
x = 120,
y = 25,
text = "Component Demo Page",
color = ui.COLOR_BLACK,
size = 12
})
-- 返回按钮
local btn_back = ui.button({
x = 20,
y = 20,
w = 60,
h = 30,
text = "Back",
on_click = function()
win:back()
end
})
-- ==================== 1. 进度条组件演示 ====================
local progress_label = ui.label({
x = 20,
y = 70,
text = "1. Progress Bar:",
color = ui.COLOR_BLACK,
size = 12
})
local progress_value = 0
local progress_bar = ui.progress_bar({
x = 20,
y = 100,
w = 200,
h = 26,
progress = progress_value
})
local btn_progress = ui.button({
x = 230,
y = 100,
w = 70,
h = 26,
text = "+10%",
on_click = function()
progress_value = progress_value + 10
if progress_value > 100 then
progress_value = 0
end
progress_bar:set_progress(progress_value)
progress_bar:set_text("Progress: " .. progress_value .. "%")
end
})
-- ==================== 2. 消息框组件演示 ====================
local msgbox_label = ui.label({
x = 20,
y = 140,
text = "2. Message Box:",
color = ui.COLOR_BLACK,
size = 12
})
local btn_msgbox = ui.button({
x = 20,
y = 170,
w = 180,
h = 30,
text = "Show MessageBox",
on_click = function()
local message_box = ui.message_box({
x = 10,
y = 100,
w = 300,
h = 150,
title = "Info",
message = "This is an exEasyUI message box demo",
buttons = { "OK", "Cancel" },
on_result = function(button_index)
log.info("component_page", "Button clicked:", button_index)
end
})
ui.add(message_box)
end
})
-- ==================== 3. 复选框组件演示 ====================
local checkbox_label = ui.label({
x = 20,
y = 220,
text = "3. Check Box:",
color = ui.COLOR_BLACK,
size = 12
})
local checkbox1 = ui.check_box({
x = 20,
y = 250,
text = "Option A",
checked = false,
on_change = function(checked)
log.info("component_page", "Option A:", checked)
end
})
local checkbox2 = ui.check_box({
x = 120,
y = 250,
text = "Option B",
checked = true,
on_change = function(checked)
log.info("component_page", "Option B:", checked)
end
})
-- ==================== 4. 输入框组件演示 ====================
local input_label = ui.label({
x = 20,
y = 300,
text = "4. Input Box:",
color = ui.COLOR_BLACK,
size = 12
})
-- 普通文本输入框
local text_input = ui.input({
x = 20,
y = 330,
w = 200,
h = 30,
placeholder = "Enter text...",
max_length = 20
})
-- 密码输入框
local password_input = ui.input({
x = 20,
y = 370,
w = 200,
h = 30,
placeholder = "Enter password...",
input_type = "password",
max_length = 16
})
-- 数字输入框
local number_input = ui.input({
x = 20,
y = 410,
w = 200,
h = 30,
placeholder = "Enter number...",
input_type = "number",
max_length = 10
})
-- ==================== 5. 下拉框组件演示 ====================
local combo_label = ui.label({
x = 20,
y = 460,
text = "5. Combo Box:",
color = ui.COLOR_BLACK,
size = 12
})
local combo_box = ui.combo_box({
x = 20,
y = 490,
w = 200,
h = 30,
options = { "Option 1", "Option 2", "Option 3" },
placeholder = "Please select",
selected = 1,
on_select = function(value, index, text)
log.info("component_page", "Selected:", text, "Index:", index)
end
})
-- ==================== 6. 图片轮播组件演示 ====================
local picture_label = ui.label({
x = 20,
y = 540,
text = "6. Image Carousel:",
color = ui.COLOR_BLACK,
size = 12
})
local picture = ui.picture({
x = 20,
y = 570,
w = 280,
h = 100,
sources = { "/luadb/1.jpg", "/luadb/2.jpg", "/luadb/3.jpg" },
autoplay = true,
interval = 2000
})
-- ==================== 7. 按钮组件演示 ====================
local button_label = ui.label({
x = 20,
y = 705,
text = "7. Buttons:",
color = ui.COLOR_BLACK,
size = 12
})
-- 普通按钮
local normal_btn = ui.button({
x = 20,
y = 735,
w = 120,
h = 30,
text = "Normal Button",
on_click = function()
log.info("component_page", "Normal button clicked")
end
})
-- 带颜色的按钮
local colored_btn = ui.button({
x = 150,
y = 735,
w = 90,
h = 30,
text = "Blue Button",
bg_color = ui.COLOR_BLUE,
text_color = ui.COLOR_WHITE,
on_click = function()
log.info("component_page", "Blue button clicked")
end
})
-- 图片按钮
local image_btn = ui.button({
x = 250,
y = 720,
w = 64,
h = 64,
src = "/luadb/4.jpg",
src_toggled = "/luadb/5.jpg",
toggle = true,
on_click = function()
log.info("component_page", "Image button clicked")
end
})
-- 添加所有组件到窗口
win:add(title)
win:add(btn_back)
win:add(progress_label)
win:add(progress_bar)
win:add(btn_progress)
win:add(msgbox_label)
win:add(btn_msgbox)
win:add(checkbox_label)
win:add(checkbox1)
win:add(checkbox2)
win:add(input_label)
win:add(text_input)
win:add(password_input)
win:add(number_input)
win:add(combo_label)
win:add(combo_box)
win:add(picture_label)
win:add(picture)
win:add(button_label)
win:add(normal_btn)
win:add(colored_btn)
win:add(image_btn)
return win
end
return component_page
6.7 default_font_page.lua
本文件为默认字体演示页面功能模块,核心业务逻辑为:
1、创建演示窗口,展示内置12号英文点阵字体的固定大小特性;
2、演示数字、符号、英文的显示效果;
3、展示默认字体的特性和限制说明;
4、提供返回主页的导航功能;
local default_font_page = {}
--[[
创建默认字体演示页面;
@api default_font_page.create(ui)
@summary 创建默认字体演示页面界面
@table ui UI库对象
@return table 默认字体演示窗口对象
@usage
-- 在子页面工厂中调用创建默认字体演示页面
local default_font_page = require("default_font_page").create(ui)
]]
function default_font_page.create(ui)
local win = ui.window({
background_color = ui.COLOR_WHITE,
x = 0, y = 0, w = 320, h = 480
})
-- 标题 - 居中显示
local title = ui.label({
x = 120, y = 25,
text = "Default Font Demo",
color = ui.COLOR_BLACK,
size = 12
})
-- 返回按钮
local btn_back = ui.button({
x = 20, y = 20,
w = 60, h = 30,
text = "Back",
on_click = function()
win:back()
end
})
-- 字体演示标题
local demo_title = ui.label({
x = 20, y = 70,
text = "Font Demo (Fixed 12pt):",
color = ui.COLOR_BLACK,
size = 12
})
-- 数字演示 - 蓝色12号
local number_demo = ui.label({
x = 20, y = 100,
text = "1. Numbers: 0123456789",
color = ui.COLOR_BLUE,
size = 12
})
-- 符号演示 - 橙色12号
local symbol_demo = ui.label({
x = 20, y = 130,
text = "2. Symbols: !@#$%^&*()_+-=[]",
color = ui.COLOR_ORANGE,
size = 12
})
-- 英文演示 - 红色12号
local text_demo = ui.label({
x = 20, y = 160,
text = "3. English: Hello World ABC",
color = ui.COLOR_RED,
size = 12
})
-- 默认字体特性说明
local feature_title = ui.label({
x = 20, y = 200,
text = "Default Font Features:",
color = ui.COLOR_BLACK,
size = 12
})
local feature1 = ui.label({
x = 20, y = 230,
text = "- Built-in 12pt bitmap font",
color = ui.COLOR_GRAY,
size = 12
})
local feature2 = ui.label({
x = 20, y = 260,
text = "- Supports English, numbers, symbols",
color = ui.COLOR_GRAY,
size = 12
})
local feature3 = ui.label({
x = 20, y = 290,
text = "- Fast startup, low resource usage",
color = ui.COLOR_GRAY,
size = 12
})
local feature4 = ui.label({
x = 20, y = 320,
text = "- Fixed 12pt font size",
color = ui.COLOR_GRAY,
size = 12
})
-- 启用滚动以显示完整内容
win:enable_scroll({
direction = "vertical",
content_height = 400,
threshold = 10
})
-- 添加所有组件到窗口
win:add(title)
win:add(btn_back)
win:add(demo_title)
win:add(number_demo)
win:add(symbol_demo)
win:add(text_demo)
win:add(feature_title)
win:add(feature1)
win:add(feature2)
win:add(feature3)
win:add(feature4)
return win
end
return default_font_page
七、显示效果展示
7.1 硬件准备
- 按照硬件接线表连接所有设备
- 确保电源连接正确,通过TYPE-C USB口供电
- 检查所有接线无误,避免短路
7.2 软件配置
在main.lua中选择加载对应的模块:
-- 必须加载才能启用exeasyui的功能
ui = require("exeasyui")
-- 加载lcd、tp驱动管理功能模块
-- 1、按lcd显示驱动配置和tp触摸驱动配置进行初始化,默认使用lcd内核固件中自带的12号英文点阵字体
require("hw_default_font_drv")
-- 加载exeassyui扩展库实现的用户界面功能模块
-- 实现多页面切换、触摸事件分发和界面渲染功能
-- 包含主页、组件演示页、默认字体演示页
require("ui_main")
7.3 软件烧录
- 使用Luatools烧录最新内核固件
- 下载并烧录本项目所有脚本文件
- 将字体文件和图片文件随脚本文件一起烧录到脚本分区
- 烧录成功后设备自动重启后开始运行
7.4 功能测试
7.4.1 主页面操作
- 设备启动后显示主页面,包含两个功能按钮
- 查看系统标题和版本信息
- 点击各功能按钮进入对应演示页面

7.4.2 组件演示页面
- 测试进度条组件的动态更新
- 体验消息框的弹出和按钮响应
- 操作复选框查看状态变化
- 在输入框中输入文本测试
- 使用下拉框选择选项
- 查看图片轮播效果(如有图片文件)


7.4.3 字体演示页面
- 默认字体页:查看固定 12 号字体的颜色和英文显示
- 在各页面使用返回按钮回到主页

7.5 预期效果
- 系统启动:正常初始化,显示主页面
- 页面切换:流畅的页面过渡效果
- 组件交互:所有 UI 组件响应灵敏
- 字体显示:各字体页面正常显示,动态调整功能正常
- 触摸操作:准确的触摸定位和事件响应
八、常见问题
- 显示异常:检查 LCD 接线,确认对应驱动文件中的硬件参数正确
- 触摸无响应:检查 I2C 接线,确认触摸芯片型号配置正确
- 图片无法显示:确认图片文件已正确烧录到指定路径
- 系统卡顿:调整
ui_main.lua中的刷新率参数