AirUI 组件演示
一、概述
本项目是基于 AirUI 图形用户界面库的完整组件演示程序,展示了多种 UI 组件和功能模块。每个演示模块独立运行,通过主程序 main.lua 统一调度管理。
二、演示功能概述
2.1 核心驱动模块
1、main.lua - 主程序入口
-
项目初始化和版本定义
-
系统任务调度和看门狗配置
- 演示模块的选择和加载
2、lcd_drv.lua - LCD 显示驱动
- 初始化 LCD 屏幕及背光
- 配置显示参数和缓冲区
- 初始化 AirUI 框架
3、tp_drv.lua - 触摸面板驱动
- 初始化 GT911 触摸控制器
- 配置 I2C 通信和触摸回调
- 绑定触摸设备到 AirUI 输入系统
2.2 基础组件演示
airui_label.lua- 标签组件演示airui_button.lua- 按钮组件演示airui_image.lua- 图片组件演示airui_container.lua- 容器组件演示airui_bar.lua- (动态)进度条组件演示
2.3 交互组件演示
airui_switch.lua- 开关组件演示airui_dropdown.lua- 下拉框组件演示airui_input.lua- 输入框和虚拟键盘演示airui_msgbox.lua- 消息框组件演示
2.4 布局与高级组件演示
airui_table.lua- 表格组件演示airui_tabview.lua- 选项卡组件演示airui_win.lua- 窗口组件演示airui_switch_page.lua- 多页面切换功能演示airui_all_component.lua- 所有组件综合演示
2.5 字体渲染演示
airui_hzfont.lua- HzFont 矢量字体特性演示
三、准备硬件环境

1、Air780EGH 核心板 × 1
2、AirLCD_1010 触摸配件板 × 1
3、母对母杜邦线 × 17,杜邦线太长的话,会出现 spi 通信不稳定的现象;
4、TYPE-C 数据线 × 1
5、Air780EGH 核心板和 AirLCD_1010 配件板的硬件接线方式为
- Air780EGH 核心板通过 TYPE-C USB 口供电(核心板正面开关拨到 ON 一端),此种供电方式下,VDD_EXT 引脚为 3.3V,可以直接给 AirLCD_1010 配件板供电;
- 为了演示方便,所以 Air780EGH 核心板上电后直接通过 VBAT 引脚给 AirLCD_1010 配件板供电;
- 客户在设计实际项目时,一般来说,需要通过一个 GPIO 来控制 LDO 给配件板供电,这样可以灵活地控制配件板的供电,可以使项目的整体功耗降到最低;
LCD 显示屏接线
| Air780EHM/Air780EHV/Air780EGH 核心板 | 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 |
| 20/GPIO24 | INT |
四、准备软件环境
4.1 软件环境
在开始实践本示例之前,先筹备一下软件环境:
1、烧录工具:Luatools 下载调试工具
2、内核固件:本demo开发测试时使用的固件为LuatOS-SoC_V2024_Air780EGH 14号固件(请选择支持 airui 功能固件),所以你如果要测试本demo时,可以直接使用最新版本支持 airui 功能的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;
4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件
准备好软件环境之后,接下来查看如何烧录项目文件到Air780EGH核心板,将本篇文章中演示使用的项目文件烧录到Air780EGH核心板中。
4.2 API 介绍
airui-功能强大的图形化开发:https://docs.openluat.com/osapi/core/airui/
五、程序结构
ui/airui/single
│── main.lua
│── images
│── xxx.jpg
│── airui_all_component.lua
│── airui_bar.lua
│── airui_button.lua
│── airui_container.lua
│── airui_dropdown.lua
│── airui_hzfont.lua
│── airui_image.lua
│── airui_input.lua
│── airui_label.lua
│── airui_msgbox.lua
│── airui_switch.lua
│── airui_switch_page.lua
│── airui_table.lua
│── airui_tabview.lua
│── airui_win.lua
│── lcd_drv.lua
│── tp_drv.lua
│── readme.md
5.1 文件说明
1、main.lua:整个项目的入口点。它负责初始化系统环境
2、images:
xxx.jpg:演示图片文件(和lua脚本文件一起烧录,会自动放置在/luadb/目录下)
3、airui_all_component.lua:所有组件综合演示
4、airui_bar.lua:(动态)进度条组件演示
5、airui_button.lua:按钮组件演示
6、airui_container.lua:容器组件演示
7、airui_dropdown.lua:下拉框组件演示
8、airui_hzfont.lua:HzFont 矢量字体特性演示
9、airui_image.lua:图片组件演示
10、airui_input.lua:输入框和虚拟键盘演示
11、airui_label.lua:标签组件演示
12、airui_msgbox.lua:消息框组件演示
13、airui_switch.lua:开关组件演示
14、airui_switch_page.lua:多页面切换功能演示
15、airui_table.lua:表格组件演示
17、airui_win.lua:窗口组件演示
18、lcd_drv.lua:LCD 显示驱动
19、tp_drv.lua:触摸面板驱动
六、代码详解
6.1 main.lua
主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。
-- 加载显示驱动
require("lcd_drv")
-- 加载触摸驱动
require("tp_drv")
-- 引入演示模块(每次只选择一个运行)
-- require("airui_label") --动态更新标签演示
-- require("airui_button") --按钮演示
-- require("airui_image") --图片显示演示
-- require("airui_container") --容器演示
-- require("airui_bar") --动态进度条演示
-- require("airui_dropdown") --下拉框演示
-- require("airui_switch") --开关组件演示
-- require("airui_msgbox") --消息框组件演示
-- require("airui_input") --输入框和键盘演示
-- require("airui_tabview") --选项卡演示
-- require("airui_table") --表格演示
-- require("airui_win") --标签窗口演示
require("airui_all_component") --所有组件综合演示
-- require("airui_switch_page") --页面切换演示
-- require("airui_hzfont") --内置软件矢量字体演示
-- 用户代码已结束
-- 结尾总是这一句
sys.run()
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
6.2 airui_all_component.lua
本文件演示所有AirUI组件的综合用法,展示完整UI界面。
local function ui_main()
-- 初始化硬件
-- 创建主容器(竖屏尺寸)
local main_container = airui.container({
x = 0,
y = 0,
w = 320, -- 改为320
h = 480, -- 保持480
color = 0xF5F5F5,
})
-- 1. 标题区域
local title_bar = airui.container({
parent = main_container,
x = 0,
y = 0,
w = 320,
h = 50,
color = 0x007AFF,
})
local title_label = airui.label({
parent = title_bar,
text = "AirUI组件演示",
x = 10,
y = 10,
w = 300,
h = 30,
})
-- 2. 内容区域(可滚动区域)
local scroll_container = airui.container({
parent = main_container,
x = 0,
y = 50, -- 从标题栏下面开始
w = 320,
h = 380, -- 为底部键盘留出空间
color = 0xFFFFFF,
})
-- 2.1 文本输入框组件
airui.label({
parent = scroll_container,
text = "文本输入",
x = 10,
y = 10,
w = 300,
h = 20,
})
local text_input = airui.textarea({
parent = scroll_container,
x = 10,
y = 35,
w = 300,
h = 40,
max_len = 50,
text = "示例文本",
placeholder = "请输入...",
on_text_change = function(self, text)
log.info("textarea", "输入: " .. text)
end
})
-- 2.2 进度条组件
airui.label({
parent = scroll_container,
text = "进度条",
x = 10,
y = 85,
w = 100,
h = 20,
})
local progress_bar = airui.bar({
parent = scroll_container,
x = 10,
y = 110,
w = 300,
h = 15,
value = 65,
bg_color = 0xE0E0E0,
indicator_color = 0x4CAF50,
radius = 7,
})
-- 2.3 按钮组件 - 横向排列
local btn_container = airui.container({
parent = scroll_container,
x = 10,
y = 135,
w = 300,
h = 50,
color = 0xFFFFFF,
})
local test_btn = airui.button({
parent = btn_container,
x = 0,
y = 0,
w = 145,
h = 40,
text = "更新进度",
on_click = function()
local current = progress_bar:get_value()
local new_value = current + 10
if new_value > 100 then
new_value = 0
end
progress_bar:set_value(new_value, true)
log.info("progress", "进度更新为: " .. new_value .. "%")
end
})
local msgbox_btn = airui.button({
parent = btn_container,
x = 155,
y = 0,
w = 145,
h = 40,
text = "显示消息",
on_click = function()
local msgbox = airui.msgbox({
title = "提示",
text = "这是消息框演示\n点击确定关闭",
buttons = { "确定", "取消" },
timeout = 2000,
on_action = function(self, label)
log.info("msgbox", "点击了: " .. label)
end
})
msgbox:show()
end
})
-- 2.4 开关组件
local switch_container = airui.container({
parent = scroll_container,
x = 10,
y = 195,
w = 300,
h = 40,
color = 0xFFFFFF,
})
airui.label({
parent = switch_container,
text = "开关",
x = 0,
y = 10,
w = 60,
h = 20,
})
local is_on = true
local toggle_switch = airui.switch({
parent = switch_container,
x = 70,
y = 5,
w = 60,
h = 30,
checked = true,
on_change = function(self)
is_on = not is_on
if is_on then
log.info("当前状态: 开")
else
log.info("当前状态: 关")
end
end
})
-- 2.5 下拉框组件
airui.label({
parent = scroll_container,
text = "下拉选择",
x = 10,
y = 245,
w = 100,
h = 20,
})
local dropdown = airui.dropdown({
parent = scroll_container,
x = 10,
y = 270,
w = 300,
h = 40,
options = { "选项一", "选项二", "选项三", "选项四" },
default_index = 0,
on_change = function(self, index)
local texts = { "选项一", "选项二", "选项三", "选项四" }
log.info("dropdown", "选择了: " .. texts[index + 1])
end
})
-- 2.6 表格组件
airui.label({
parent = scroll_container,
text = "数据表格",
x = 10,
y = 320,
w = 300,
h = 20,
})
local data_table = airui.table({
parent = scroll_container,
x = 10,
y = 345,
w = 300,
h = 120,
rows = 3,
cols = 3,
col_width = { 100, 80, 100 },
border_color = 0xCCCCCC
})
-- 设置表格内容
data_table:set_cell_text(0, 0, "姓名")
data_table:set_cell_text(0, 1, "年龄")
data_table:set_cell_text(0, 2, "城市")
data_table:set_cell_text(1, 0, "张三")
data_table:set_cell_text(1, 1, "25")
data_table:set_cell_text(1, 2, "北京")
data_table:set_cell_text(2, 0, "李四")
data_table:set_cell_text(2, 1, "30")
data_table:set_cell_text(2, 2, "上海")
-- 3. 创建虚拟键盘(放在底部)
local keyboard = airui.keyboard({
x = 0,
y = -20, -- 距离底边10像素
w = 320,
h = 200,
mode = "text",
target = text_input,
auto_hide = true,
on_commit = function()
log.info("input", "输入内容: ", text_input:get_text())
end,
})
-- 4. 底部状态栏
local status_bar = airui.container({
parent = main_container,
x = 0,
y = 460, -- 从460位置开始
w = 320,
h = 20,
color = 0x333333,
})
airui.label({
parent = status_bar,
text = "AirUI Demo v1.0",
x = 10,
y = 2,
w = 300,
h = 16,
})
end
sys.taskInit(ui_main)
6.3 airui_bar.lua
本文件演示airui.bar组件的用法,展示动态变化的进度条。
local direction = 1 -- 变化方向
local current = 0 -- 当前值
local function ui_main()
-- 初始化硬件
-- 创建进度条
local progress = airui.bar({
x = 20,
y = 200,
w = 280,
value = 30
})
-- 主循环
while true do
-- 更新进度条值
current = current + direction
if current >= 100 then
direction = -1
elseif current <= 0 then
direction = 1
end
progress:set_value(current, true)
sys.wait(50)
end
end
sys.taskInit(ui_main)
6.4 airui_button.lua
本文件演示airui.button组件的用法,展示可点击按钮。
local function ui_main()
-- 初始化硬件
-- 创建按钮
local btn = airui.button({
x = 20,
y = 80,
on_click = function()
log.info("btn", "按钮被点击了")
end
})
end
sys.taskInit(ui_main)
6.5 airui_container.lua
本文件演示airui.container组件的用法,展示如何创建容器并添加子组件。
local function ui_main()
-- 初始化硬件
-- 创建红色容器
local box = airui.container({
x = 100,
y = 100,
w = 100,
h = 100,
color = 0xff0000
})
-- 在容器中添加标签
local label = airui.label({
parent = box, -- 指定父容器
text = "容器中的标签",
x = 10,
y = 50,
w = 100,
h = 100,
})
end
sys.taskInit(ui_main)
6.6 airui_dropdown.lua
本文件演示airui.dropdown组件的用法,展示下拉选择功能。
local function ui_main()
-- 初始化硬件
-- 创建标签显示选择结果
local label = airui.label({
text = "请选择选项",
x = 50,
y = 80,
w = 200,
h = 40,
})
-- 创建下拉框
local dd = airui.dropdown({
x = 50,
y = 120,
w = 120,
h = 40,
options = { "选项A", "选项B", "选项C" },
default_index = 1,
on_change = function(self, index)
-- 更新标签显示选择结果
local texts = { "选项A", "选项B", "选项C" }
label:set_text("选择了: " .. texts[index + 1])
end
})
end
sys.taskInit(ui_main)
6.7 airui_hzfont.lua
本文件演示HzFont矢量字体的各项特性,包括全字号无级缩放、抗锯齿优化和字体使用自由。
local function ui_main()
-- 初始化硬件
-- 创建主容器(竖屏尺寸)
local main_container = airui.container({
x = 0,
y = 0,
w = 320,
h = 480,
color = 0xFFFFFF, -- 白色背景
})
-- 标题区域
local title_bar = airui.container({
parent = main_container,
x = 0,
y = 0,
w = 320,
h = 60,
color = 0x2196F3, -- 蓝色背景
})
local title_label = airui.label({
parent = title_bar,
text = "HzFont矢量字体演示",
x = 10,
y = 15,
w = 300,
h = 30,
})
-- 创建可滚动内容区域
local scroll_area = airui.container({
parent = main_container,
x = 0,
y = 60, -- 从标题栏下方开始
w = 320,
h = 400, -- 留出底部空间
color = 0xF8F9FA, -- 浅灰色背景
})
-- 第1个特性卡片:全字号无级缩放
local card1 = airui.container({
parent = scroll_area,
x = 10,
y = 20,
w = 300,
h = 120,
color = 0xFFFFFF,
radius = 8, -- 圆角
})
local card1_title = airui.label({
parent = card1,
text = "特性一:全字号无级缩放",
x = 10,
y = 10,
w = 280,
h = 25,
})
local card1_content = airui.label({
parent = card1,
text = "完整支持12-255字号,可随意指定任意大小,满足精细化界面排版需求。提供多种字号展示效果。",
x = 10,
y = 40,
w = 280,
h = 70,
})
-- 第2个特性卡片:智能抗锯齿优化
local card2 = airui.container({
parent = scroll_area,
x = 10,
y = 150, -- 与上一个卡片保持间距
w = 300,
h = 120,
color = 0xFFFFFF,
radius = 8,
})
local card2_title = airui.label({
parent = card2,
text = "特性二:智能抗锯齿优化",
x = 10,
y = 10,
w = 280,
h = 25,
})
local card2_content = airui.label({
parent = card2,
text = "支持可调节的抗锯齿等级,有效平滑字体边缘,提升显示细腻度与视觉效果。适合不同尺寸文字渲染。",
x = 10,
y = 40,
w = 280,
h = 70,
})
-- 第3个特性卡片:字体使用高度自由
local card3 = airui.container({
parent = scroll_area,
x = 10,
y = 280, -- 与上一个卡片保持间距
w = 300,
h = 120,
color = 0xFFFFFF,
radius = 8,
})
local card3_title = airui.label({
parent = card3,
text = "特性三:字体使用高度自由",
x = 10,
y = 10,
w = 280,
h = 25,
})
local card3_content = airui.label({
parent = card3,
text = "既可使用固件内置字库快速上手,也能轻松加载外部.ttf字体文件,便于对定制字体与多国语言的支持。",
x = 10,
y = 40,
w = 280,
h = 70,
})
-- 底部说明区域
local bottom_info = airui.container({
parent = main_container,
x = 0,
y = 460, -- 放在底部
w = 320,
h = 20,
color = 0x333333,
})
airui.label({
parent = bottom_info,
text = "HzFont矢量字体 v1.0",
x = 10,
y = 2,
w = 300,
h = 16,
})
end
sys.taskInit(ui_main)
6.8 airui_image.lua
本文件演示airui.image组件的用法,展示图片显示功能。
local function ui_main()
-- 初始化硬件
-- 创建可点击图片
local img = airui.image({
src = "/luadb/dingwei_50x50.png",
x = 100,
y = 176,
w = 128,
h = 128,
opacity = 100, -- 透明度
on_click = function(self)
log.info("image", "图片被点击了")
end
})
-- 创建半透明图片
local img1 = airui.image({
src = "/luadb/logo.jpg",
x = 20,
y = 20,
w = 80,
h = 80,
})
end
sys.taskInit(ui_main)
6.9 airui_input.lua
本文件演示airui.textarea和airui.keyboard组件的用法,展示文本输入功能。
local function ui_main()
-- 初始化硬件
-- 创建虚拟键盘
local keyboard = airui.keyboard({
x = 0,
y = -10,
w = 320,
h = 200,
mode = "text",
})
-- 创建文本输入框
local textarea = airui.textarea({
x = 10,
y = 50,
w = 300,
h = 100,
max_len = 512,
text = "在这里输入文字",
placeholder = "点击输入...",
keyboard = keyboard
})
end
sys.taskInit(ui_main)
6.10 airui_label.lua
本文件演示airui.label组件的用法,展示文本标签功能。
local function ui_main()
-- 初始化硬件
-- 创建文本标签
local label1 = airui.label({
text = "Hello, World!",
x = 20,
y = 80,
w = 100,
h = 40,
})
-- 创建图标标签
local label2 = airui.label({
symbol = airui.SYMBOL_SETTINGS,
x = 120,
y = 80,
w = 20,
h = 20,
on_click = function(self)
log.info("label2", "设置图标被点击")
end
})
end
sys.taskInit(ui_main)
6.11 airui_msgbox.lua
本文件演示airui.msgbox组件的用法,展示消息提示框功能。
local function ui_main()
-- 初始化硬件
-- 创建消息框
local box = airui.msgbox({
title = "通知",
text = "2026年你会发财!",
buttons = { "确定" },
on_action = function(self, label)
if label == "确定" then
self:hide()
end
end
})
end
sys.taskInit(ui_main)
6.12 airui_switch.lua
本文件演示airui.switch组件的用法,展示开关切换功能。
local function ui_main()
-- 初始化硬件
-- 创建标签显示状态
local label = airui.label({
text = "当前状态: 开",
x = 20,
y = 80,
w = 150,
h = 40,
})
-- 创建开关
-- 使用一个变量来跟踪当前状态
local is_on = true -- 初始为ON,与switch的checked=true对应
local sw = airui.switch({
x = 20,
y = 120,
checked = true,
on_change = function()
-- 切换状态
is_on = not is_on
-- 根据状态更新文本
if is_on then
label:set_text("当前状态: 开")
else
label:set_text("当前状态: 关")
end
end
})
end
sys.taskInit(ui_main)
6.13 airui_switch_page.lua
本文件演示如何使用容器组件实现多页面切换功能。
local current_page = 1
local total_pages = 3
local pages = {}
local function ui_main()
-- 初始化硬件
-- 创建主容器(竖屏尺寸)
local main_container = airui.container({
x = 0,
y = 0,
w = 320, -- 改为320
h = 480, -- 保持480
color = 0xF8F9FA,
})
-- 创建标题栏
local title_bar = airui.container({
parent = main_container,
x = 0,
y = 0,
w = 320, -- 改为320
h = 60, -- 缩小高度
color = 0x007AFF,
})
local title_label = airui.label({
parent = title_bar,
text = "页面切换演示",
x = 10,
y = 15,
w = 200,
h = 30,
})
local page_indicator = airui.label({
parent = title_bar,
text = "第1页/共3页",
x = 220,
y = 15,
w = 90,
h = 30,
})
-- 创建内容区域
local content_area = airui.container({
parent = main_container,
x = 10, -- 左边距
y = 70, -- 标题栏下方
w = 300, -- 改为300
h = 300, -- 减小高度,为导航栏留空间
color = 0xFFFFFF,
radius = 8, -- 圆角
})
-- 创建三个页面
for i = 1, total_pages do
pages[i] = airui.container({
parent = content_area,
x = 0,
y = 0,
w = 300, -- 改为300
h = 300,
color = 0xFFFFFF,
})
-- 设置页面初始状态(只显示第一个页面)
if i ~= 1 then
pages[i]:set_hidden(true)
end
-- 为每个页面添加不同的内容
if i == 1 then
-- 第一页:欢迎页面
local welcome_label = airui.label({
parent = pages[i],
text = "欢迎使用页面切换演示",
x = 0,
y = 40,
w = 300,
h = 40,
})
local desc_label = airui.label({
parent = pages[i],
text = "这是一个演示多页面切换功能的示例\n使用容器组件实现页面切换\n点击下方按钮切换页面",
x = 0,
y = 100,
w = 300,
h = 80,
})
elseif i == 2 then
-- 第二页:设置页面
airui.label({
parent = pages[i],
text = "设置页面",
x = 0,
y = 20,
w = 300,
h = 30,
})
-- 设置项目1 - 开关
local setting1_container = airui.container({
parent = pages[i],
x = 20,
y = 60,
w = 260,
h = 40,
color = 0xFFFFFF,
})
airui.label({
parent = setting1_container,
text = "开关设置",
x = 0,
y = 10,
w = 120,
h = 30,
})
local switch1 = airui.switch({
parent = setting1_container,
x = 130,
y = 5,
w = 60,
h = 30,
checked = true,
on_change = function()
log.info("page2", "开关1状态改变")
end
})
-- 设置项目2 - 进度条
local setting2_container = airui.container({
parent = pages[i],
x = 20,
y = 110,
w = 260,
h = 50,
color = 0xFFFFFF,
})
airui.label({
parent = setting2_container,
text = "亮度调节",
x = 0,
y = 15,
w = 120,
h = 30,
})
local brightness_bar = airui.bar({
parent = setting2_container,
x = 130,
y = 15,
w = 120,
h = 20,
value = 75,
indicator_color = 0xFF9800,
})
-- 设置项目3 - 下拉框
local setting3_container = airui.container({
parent = pages[i],
x = 20,
y = 170,
w = 260,
h = 60,
color = 0xFFFFFF,
})
airui.label({
parent = setting3_container,
text = "模式选择",
x = 0,
y = 20,
w = 120,
h = 30,
})
local mode_dropdown = airui.dropdown({
parent = setting3_container,
x = 130,
y = 15,
w = 120,
h = 40,
options = { "自动模式", "手动模式", "节能模式" },
default_index = 0,
})
elseif i == 3 then
-- 第三页:数据页面
airui.label({
parent = pages[i],
text = "数据展示",
x = 0,
y = 20,
w = 300,
h = 30,
})
-- 创建数据表格(适配竖屏)
local data_table = airui.table({
parent = pages[i],
x = 10,
y = 60,
w = 280, -- 减小宽度
h = 220,
rows = 5,
cols = 4,
col_width = { 70, 70, 70, 70 },
border_color = 0xCCCCCC
})
-- 设置表头
data_table:set_cell_text(0, 0, "设备")
data_table:set_cell_text(0, 1, "温度")
data_table:set_cell_text(0, 2, "湿度")
data_table:set_cell_text(0, 3, "状态")
-- 设置数据
data_table:set_cell_text(1, 0, "传感器1")
data_table:set_cell_text(1, 1, "25°C")
data_table:set_cell_text(1, 2, "65%")
data_table:set_cell_text(1, 3, "正常")
data_table:set_cell_text(2, 0, "传感器2")
data_table:set_cell_text(2, 1, "28°C")
data_table:set_cell_text(2, 2, "70%")
data_table:set_cell_text(2, 3, "正常")
data_table:set_cell_text(3, 0, "传感器3")
data_table:set_cell_text(3, 1, "22°C")
data_table:set_cell_text(3, 2, "60%")
data_table:set_cell_text(3, 3, "正常")
data_table:set_cell_text(4, 0, "传感器4")
data_table:set_cell_text(4, 1, "30°C")
data_table:set_cell_text(4, 2, "75%")
data_table:set_cell_text(4, 3, "警告")
end
end
-- 创建底部导航栏
local nav_bar = airui.container({
parent = main_container,
x = 10,
y = 380, -- 调整位置
w = 300,
h = 90, -- 增加高度以适应竖屏按钮排列
color = 0xFFFFFF,
})
-- 创建导航按钮容器
local btn_container = airui.container({
parent = nav_bar,
x = 0,
y = 0,
w = 300,
h = 90,
color = 0xFFFFFF,
})
-- 创建上一页和下一页按钮(横向排列)
local prev_next_container = airui.container({
parent = btn_container,
x = 0,
y = 0,
w = 300,
h = 40,
color = 0xFFFFFF,
})
local prev_btn = airui.button({
parent = prev_next_container,
x = 0,
y = 0,
w = 140,
h = 40,
text = "上一页",
on_click = function()
if current_page > 1 then
-- 隐藏当前页面
pages[current_page]:set_hidden(true)
current_page = current_page - 1
-- 显示新页面
pages[current_page]:set_hidden(false)
page_indicator:set_text("第" .. current_page .. "页/共3页")
log.info("page_switch", "切换到第 " .. current_page .. " 页")
end
end
})
local next_btn = airui.button({
parent = prev_next_container,
x = 160,
y = 0,
w = 140,
h = 40,
text = "下一页",
on_click = function()
if current_page < total_pages then
-- 隐藏当前页面
pages[current_page]:set_hidden(true)
current_page = current_page + 1
-- 显示新页面
pages[current_page]:set_hidden(false)
page_indicator:set_text("第" .. current_page .. "页/共3页")
log.info("page_switch", "切换到第 " .. current_page .. " 页")
end
end
})
-- 创建页面快速跳转按钮(横向排列)
local page_btn_container = airui.container({
parent = btn_container,
x = 0,
y = 50,
w = 300,
h = 40,
color = 0xFFFFFF,
})
local page_btn_x = 0
for i = 1, total_pages do
local btn_text = "第" .. i .. "页"
local btn_width = 90 -- 每个按钮宽度
local page_btn = airui.button({
parent = page_btn_container,
x = page_btn_x,
y = 0,
w = btn_width,
h = 40,
text = btn_text,
on_click = function()
-- 隐藏所有页面
for j = 1, total_pages do
pages[j]:set_hidden(true)
end
-- 显示选中的页面
current_page = i
pages[current_page]:set_hidden(false)
page_indicator:set_text("第" .. current_page .. "页/共3页")
log.info("page_switch", "跳转到第 " .. current_page .. " 页")
end
})
page_btn_x = page_btn_x + btn_width + 10 -- 按钮间距
end
end
sys.taskInit(ui_main)
6.14 airui_table.lua
本文件演示airui.table组件的用法,展示表格功能。
local function ui_main()
-- 初始化硬件
-- 创建3行3列的表格
local tbl = airui.table({
x = 10,
y = 10,
h = 200,
w = 310,
rows = 3,
cols = 3
})
-- 设置表格标题
tbl:set_cell_text(0, 0, "姓名")
tbl:set_cell_text(0, 1, "年龄")
tbl:set_cell_text(0, 2, "城市")
-- 设置表格内容
tbl:set_cell_text(1, 0, "张三")
tbl:set_cell_text(1, 1, "25")
tbl:set_cell_text(1, 2, "北京")
tbl:set_cell_text(2, 0, "李四")
tbl:set_cell_text(2, 1, "30")
tbl:set_cell_text(2, 2, "上海")
end
sys.taskInit(ui_main)
6.15 airui_tabview.lua
本文件演示airui.tabview组件的用法,展示多页面切换功能。
local function ui_main()
-- 初始化硬件
-- 创建选项卡视图
local tv = airui.tabview({
x = 0,
y = 0,
w = 320,
h = 480,
tabs = { "页面A", "页面B", "页面C", "页面D", "页面E" }
})
-- 获取各个页面容器
local page1 = tv:get_content(0)
local page2 = tv:get_content(1)
local page3 = tv:get_content(2)
local page4 = tv:get_content(3)
local page5 = tv:get_content(4)
-- 在每个页面中添加标签
airui.label({ parent = page1, text = "这是页面A", x = 100, y = 80 })
airui.label({ parent = page2, text = "这是页面B", x = 100, y = 80 })
airui.label({ parent = page3, text = "这是页面C", x = 100, y = 80 })
airui.label({ parent = page4, text = "这是页面D", x = 100, y = 80 })
airui.label({ parent = page5, text = "这是页面E", x = 100, y = 80 })
end
sys.taskInit(ui_main)
6.16 airui_win.lua
本文件演示airui.win组件的用法,展示窗口功能。
local function ui_main()
-- 初始化硬件
-- 创建窗口
local win1 = airui.win({
title = "示例窗口",
x = 0,
y = 0,
w = 320,
h = 400,
close_btn = true,
auto_center = false,
style = "radius",
on_close = function(self)
log.info("win", "窗口已关闭")
end
})
-- 在窗口中添加标签
local label1 = airui.label({
parent = win1,
text = "窗口中的内容",
x = 20,
y = 20,
})
-- 当前版本子组件还需再添加进win组件,后续版本可能添加为父级即可
win1:add_content(label1)
end
sys.taskInit(ui_main)
6.17 lcd_drv.lua
LCD显示驱动模块,基于lcd核心库。
local function lcd_drv_init()
local result = lcd.init("st7796",
{
pin_pwr = 1, -- 背光控制引脚GPIO端口号
port = lcd.HWID_0, -- 驱动端口
pin_rst = 36, -- lcd复位引脚
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 不同屏幕方向会有差异)
})
log.info("lcd.init", result)
if result then
-- 开启缓冲区, 刷屏速度会加快, 但也消耗2倍屏幕分辨率的内存
lcd.setupBuff(nil, true)
lcd.autoFlush(false)
-- 初始化AirUI
local width, height = lcd.getSize()
local result = airui.init(width, height)
if not result then
log.error("airui", "init failed")
return result
end
-- 加载中文字体
if rtos.bsp() ~= "Air8101" then
-- PC端/Air8000/780EHM 从14号固件/114号固件中加载hzfont字库,从而支持12-255~号中文显示
airui.font_load({
type = "hzfont", -- 字体类型,可选 "hzfont" 或 "bin"
path = nil, -- 字体路径,对于 "hzfont",传 nil 则使用内置字库
size = 20, -- 字体大小,默认 16
cache_size = 1048, -- 缓存字数大小,默认 2048
antialias = 1, -- 抗锯齿等级1-3,默认 1
})
else
-- Air8101使用104号固件将字体文件烧录到文件系统,从文件系统中加载hzfont字库,从而支持12-255号中文显示
airui.font_load({
type = "hzfont", -- 字体类型,可选 "hzfont" 或 "bin"
path = "/MiSans_gb2312.ttf", -- 字体路径,对于 "hzfont",传 nil 则使用内置字库
size = 20, -- 字体大小,默认 16
cache_size = 1048, -- 缓存字数大小,默认 2048
antialias = 1, -- 抗锯齿等级1-3,默认 1
-- load_to_psram= true,
global = true
})
end
-- 开启背光引脚供电
gpio.setup(1, 1)
-- 查询当前固件内AirUI核心库版本,V1.0.3新增接口
log.info("airui", "version -> " .. airui.version())
return result
end
end
lcd_drv_init()
6.18 tp_drv.lua
触摸面板驱动模块,基于tp核心库。
local function tp_drv_init()
-- 初始化硬件I2C
i2c.setup(1, i2c.SLOW) -- 初始化I2C 1,设置为低速模式
-- 此处触摸IC数据读取使用的是硬件I2C接口
-- 参数说明:
-- "gt911": 触摸控制器型号
-- port: I2C接口
-- pin_rst: 复位引脚编号
-- pin_int: 中断引脚编号
-- w: 触摸面板宽度
-- h: 触摸面板高度
local result = tp.init("gt911", { port = 1, pin_rst = 0xff, pin_int = gpio.WAKEUP0, w = 320, h = 480 })
log.info("tp.init", result)
if rtos.bsp() ~= "PC" then
-- 绑定触摸设备到AirUI输入设备
airui.device_bind_touch(result)
-- 在PC模拟器上启用系统键盘输入
airui.keyboard_enable_system(true)
else
if not result then
log.error("ui_main", "触摸初始化失败")
return result
else
-- 绑定触摸设备到AirUI输入设备
return airui.device_bind_touch(result)
end
end
end
tp_drv_init()
七、显示效果展示
7.1 硬件准备
- 按照硬件接线表连接所有设备
- 通过 TYPE-C USB 口供电
- 检查所有接线无误
7.2 软件配置
在 main.lua 中选择要运行的演示模块:
-- 加载显示驱动
require("lcd_drv")
-- 加载触摸驱动
require("tp_drv")
-- 引入演示模块(每次只选择一个运行)
-- require("airui_label") --动态更新标签演示
-- require("airui_button") --按钮演示
-- require("airui_image") --图片显示演示
-- require("airui_container") --容器演示
-- require("airui_bar") --动态进度条演示
-- require("airui_dropdown") --下拉框演示
-- require("airui_switch") --开关组件演示
-- require("airui_msgbox") --消息框组件演示
-- require("airui_input") --输入框和键盘演示
-- require("airui_tabview") --选项卡演示
-- require("airui_table") --表格演示
-- require("airui_win") --标签窗口演示
require("airui_all_component") --所有组件综合演示
-- require("airui_switch_page") --页面切换演示
-- require("airui_hzfont") --内置软件矢量字体演示
7.3 软件烧录
- 使用 Luatools 烧录对应型号的最新内核固件
- 下载本项目所有脚本文件和图片文件
- 将演示图片文件(如
logo.jpg等)同.lua脚本文件一起烧录到脚本分区 - 设备自动重启后开始运行选定的演示模块
7.4 功能测试
| 组件 | 输入法 |
![]() | ![]() |
八、使用合宙 LuatOS-PC 模拟器仿真 airui
8.1 PC 模拟器说明
- 合宙 LuatOS-PC 模拟器是一个能在 win10/win11 上模拟运行 lua 脚本的仿真软件,内置 LuatOS 内核固件,运行.lua 脚本效果与实际设备类似;
- 目前 PC 模拟器可以通过 LuaTools 工具的资源管理器进行下载,所以我们需要先下载安装 LuaTools 工具,然后再通过 LuaTools 工具来下载 LuatOS-PC 模拟器,最后通过 LuatOS-PC 模拟器运行 airui演示 demo;
8.2 LuatOS-PC 模拟器安装步骤
1、点击下载:Luatools v3 下载调试工具
2、通过 LuaTools 工具下载 LuatOS-PC 模拟器
- LuaTools 工具安装完毕后,点击首页面左上角的--账户--打开资源下载
- 选择-公共资源--LuatOS 的 PC 模拟器--选择最新版本 LuatOS-PC 模拟器--点击开始下载(非刷机)


4.3 下载底层固件和上层运行脚本
- 下载运行所需固件,点击资源管理--选择 Air780EGHV的 LuatOS 固件--下载V2024版本及以上的 14/114 号固件
- 下载本演示 demo 内所有.lua 脚本文件、images 文件夹内的图片(以下图片仅是示范,请根据实际情况下载对应固件)

4.4 使用 LuatOS-PC 模拟器仿真 运行 airui 演示 demo
- 返回 Luatloos 工具首页,点击--项目管理测试

- 创建一个项目并命名

- 选择固件刚才下载的固件--点击打开,路径在 Luatools 目录下 resource\LuatOS_Air780EGH\LuatOS-SoC_VXXXX_Air780EGH(以下图片仅是示范,请根据实际情况选择对应固件)

- 将下载的 demo 图片资源和.lua文件拖入到项目管理内的脚本和资源列表区域--勾选添加默认 lib--点击模拟器运行--出来的界面就是 demo 在实际设备上运行界面的仿真,可以用鼠标进行交互(以下图片仅是示范,请根据实际情况选择对应固件和脚本)

- 如需切换 demo 内的演示内容,可打开下载脚本文件中的 mian.lua 文件,将需要演示 demo 的 require 前面的注释符"--"去掉,将不需要演示 demo 的 require 前面加上注释符“--”。修改后保存代码文件,再点击模拟器运行,就会出现所 require 的 demo 对应的界面仿真。
- 比如:需要演示下拉框组件,将 main.lua 文件中的-- require("airui_dropdown") 改为 require("airui_dropdown") ,并把其他加载的组件改为注释状态。

九、故障排除
9.1 常见问题及解决方案
1、显示异常
- 检查 LCD 接线是否存在异常
- 确认 lcd_drv.lua 内屏幕型号及其参数配置是否正确
2、触摸无响应
- 检查 I2C 接线是否存在异常
- 确认确认 tp_drv.lua 内触摸芯片型号配置正确
3、字体显示异常
- 确认选择的字体驱动与硬件匹配
- 检查固件版本是否支持所选字体
4、图片无法显示
- 确认图片文件已正确烧录
- 检查文件路径和名称是否正确
5、系统运行缓慢
- 检查是否有过多的组件同时渲染
- 适当调整刷新间隔时间
9.2 调试技巧
- 使用
log.info()输出调试信息 - 检查系统内存使用情况
- 逐步启用组件排查问题

