从 0 到 1 构建一个完整的 AGUI 前端项目的流程在 ESP32 上运行


网罗开发 (小红书、快手、视频号同名)

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员

👋 大家好,我是展菲!

📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。

📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。

💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。

📅 最新动态:2025 年 3 月 17 日

快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!

文章目录

背景介绍

AGUI 是 Espressif 基于 LVGL(Light and Versatile Graphics Library) 封装的 GUI 框架,主要用来在嵌入式屏幕上做图形化界面。

它能跑在 ESP32 / ESP32-S3 / ESP32-C3 等芯片上,并支持触控屏、字体、动画、布局、主题样式等一整套 UI 功能。

如果你来自 Web 或 App 前端背景,可以把 AGUI 理解成「运行在 MCU 上的轻量版 React + CSS」,界面描述是声明式的,逻辑也是事件驱动的。

项目结构规划

一个典型的 AGUI 项目结构如下:

css 复制代码
/agui_project
├── main/
│   ├── main.c
│   ├── ui_main.c
│   ├── ui_main.h
│   └── event_handler.c
├── components/
│   └── agui_utils/          // 可选:自定义控件或封装
├── sdkconfig
├── CMakeLists.txt
└── partition.csv

在 ESP-IDF 项目中,AGUI 通常位于 /components/agui 目录下,由 Espressif 官方或第三方导入。

一个带按钮的前端页面

这是一个简单的「Hello AGUI」示例:

按下按钮,屏幕文字会发生变化。

c 复制代码
#include "lvgl.h"
#include "esp_log.h"
#include "agui.h"

static const char *TAG = "AGUI_DEMO";

lv_obj_t *label;

// 按钮事件回调
static void btn_event_cb(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_CLICKED) {
        lv_label_set_text(label, "你点我啦!");
        ESP_LOGI(TAG, "Button clicked!");
    }
}

void app_main(void)
{
    // 初始化 AGUI
    agui_init();

    // 创建屏幕
    lv_obj_t *scr = lv_scr_act();

    // 创建标签
    label = lv_label_create(scr);
    lv_label_set_text(label, "Hello AGUI!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);

    // 创建按钮
    lv_obj_t *btn = lv_btn_create(scr);
    lv_obj_align(btn, LV_ALIGN_CENTER, 0, 40);
    lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);

    lv_obj_t *btn_label = lv_label_create(btn);
    lv_label_set_text(btn_label, "点我");
}

代码解析

  • agui_init():完成 LVGL 驱动初始化(屏幕、触控、时钟等)。
  • lv_scr_act():获取当前活跃屏幕。
  • lv_label_create() / lv_btn_create():相当于创建 UI 组件。
  • lv_obj_align():设置布局。
  • lv_obj_add_event_cb():注册事件回调(相当于前端的 onClick)。

这个 Demo 完成了最基础的"前端交互"闭环:

界面展示 → 用户输入 → UI 状态变化。

构建多页面结构

AGUI/LVGL 支持多屏幕(Screen),可以用来模拟多页面前端:

c 复制代码
lv_obj_t *screen_main;
lv_obj_t *screen_settings;

void create_main_screen(void) {
    screen_main = lv_obj_create(NULL);
    lv_obj_t *btn = lv_btn_create(screen_main);
    lv_obj_t *label = lv_label_create(btn);
    lv_label_set_text(label, "去设置页");
    lv_obj_add_event_cb(btn, goto_settings, LV_EVENT_CLICKED, NULL);
}

void create_settings_screen(void) {
    screen_settings = lv_obj_create(NULL);
    lv_obj_t *label = lv_label_create(screen_settings);
    lv_label_set_text(label, "设置页面");
}

static void goto_settings(lv_event_t *e) {
    lv_scr_load(screen_settings);
}

void app_main(void) {
    agui_init();
    create_main_screen();
    create_settings_screen();
    lv_scr_load(screen_main);
}

这就像在 Web 前端中写了一个简单的 "Router + 页面跳转" 逻辑。

样式与动画

AGUI 支持类似 CSS 的样式系统:

c 复制代码
lv_style_t style_btn;
lv_style_init(&style_btn);
lv_style_set_bg_color(&style_btn, lv_color_hex(0x4CAF50));
lv_style_set_radius(&style_btn, 10);
lv_obj_add_style(btn, &style_btn, 0);

还可以添加动画:

c 复制代码
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, btn);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_time(&a, 1000);
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_x);
lv_anim_start(&a);

这在嵌入式设备上能带来非常灵动的 UI 体验(比如呼吸动画、滑入效果、状态切换等)。

实际场景应用示例

假设你在做一个 智能家居中控屏,典型页面结构如下:

页面 功能
首页 显示温湿度、WiFi 状态、时间
控制页 灯光 / 空调开关控制
设置页 WiFi 配置、屏幕亮度调节

可以通过 AGUI 实现:

c 复制代码
void show_home_screen(void);
void show_control_screen(void);
void show_settings_screen(void);

// 全局上下文
typedef enum { PAGE_HOME, PAGE_CONTROL, PAGE_SETTINGS } PageType;
PageType current_page;

// 页面切换逻辑
void switch_page(PageType target) {
    switch(target) {
        case PAGE_HOME:
            show_home_screen();
            break;
        case PAGE_CONTROL:
            show_control_screen();
            break;
        case PAGE_SETTINGS:
            show_settings_screen();
            break;
    }
}

你可以把它理解为在 MCU 上"模拟 SPA(单页应用)"。

性能与注意事项

  1. 刷新率与内存

    • ESP32 普通 SPI 屏幕一般能做到 20--30 FPS;
    • 使用 DMA + 双缓存 可提升体验;
    • 注意减少大面积重绘。
  2. 异步与任务

    • 尽量不要在事件回调里做阻塞操作;
    • 复杂逻辑建议放到 FreeRTOS Task 中执行,然后再通过事件更新 UI。
  3. 调试技巧

    • 使用 lv_log_register_print_cb() 捕获日志;
    • 使用 LV_USE_DEBUG 打开对象检查器;
    • 可以通过 UART/USB 把日志打印到上位机。

总结

AGUI 完全可以支撑一个完整的嵌入式前端项目,从界面构建、事件交互、动画到页面管理,都能做到「像前端一样写 UI」。

它的核心优势是:

  • 轻量高效(适合 ESP32 级别设备)
  • 声明式开发体验
  • 跨屏幕、跨交互统一框架
  • 可定制控件丰富

而它的劣势也很明显:

  • 没有浏览器那样的 CSS 布局调试;
  • 内存、性能上要自己控制;
  • 多线程和 UI 更新要谨慎管理。
相关推荐
RTC老炮5 小时前
webrtc弱网-BitrateEstimator类源码分析与算法原理
网络·人工智能·算法·机器学习·webrtc
程序员烧烤5 小时前
【leetcode刷题007】leetcode116、117
算法·leetcode
一只小风华~5 小时前
学习笔记:Vue Router 中的链接匹配机制与样式控制
前端·javascript·vue.js·笔记·学习·ecmascript
Jerry_Rod5 小时前
react+umijs 项目快速学习
前端·react.js
京东云开发者5 小时前
浅析cef在win和mac上的适配
前端
uhakadotcom5 小时前
在chrome浏览器插件之中,options.html和options.js常用来做什么事情
前端·javascript·面试
西瓜树枝5 小时前
Chrome 扩展开发从入门到实践:以 Cookie 跨页提取工具为例,拆解核心模块与交互逻辑
前端·javascript·chrome
gplitems1235 小时前
Download:Blaxcut - Barbershop & Hair Salon WordPress Theme
前端