ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用Anyui网页版拖拽生成LVGL代码,嵌入式UI开发5分钟快速搞定

用Anyui网页版拖拽生成LVGL代码,嵌入式UI开发5分钟快速搞定 1. 嵌入式UI开发的老大难从“点灯工程师”到界面开发的鸿沟先聊个我观察了很久的现象。很多做嵌入式的朋友单片机基础非常扎实寄存器操作、中断优先级、DMA搬运数据这些底层活干得行云流水但一到UI开发就卡壳。我身边用Keil写STM32的老哥们提起“移植LVGL”四个字脸上表情多少有点微妙。确实LVGL虽然是个开源免费、对硬件要求友好的图形库但它的学习曲线对纯MCU背景的开发者并不友好你要理解显示缓冲区的管理机制要配置显示屏的驱动时序还要搞明白事件回调、样式继承、对象树这些概念。最让人头疼的还不是这些基础概念而是“从0到1”那一脚。你辛辛苦苦把LVGL库编译通过在裸机上好不容易画出一个带背景色的矩形然后呢让你手动写一个带圆角、带阴影、带动态效果的按钮光状态切换的代码就够你折腾一整天。更别提做整个界面了几十个控件一一摆放、对齐、调色、绑事件手写代码写到怀疑人生。我就是从这条路上走过来的所以特别理解那种感受。后来有一次逛技术社区看到有人提到Anyui这个网页版工具说可以在浏览器里拖拖拽拽就把UI设计好然后直接导出LVGL代码全程不用安装任何软件。我一开始是不太信的毕竟嵌入式圈子里画饼的工具太多了但抱着试一试的心态用了一下确实有点惊艳到我了。这也是我今天想认真写一篇文章的原因。这篇内容不是什么高深的技术剖析而是纯粹想给那些还在被LVGL界面开发折磨的新手朋友指一条捷径用Anyui网页版做UI设计导出代码后再和LVGL工程对接整个流程跑通下来熟练之后真的只需要几分钟。文章会覆盖工具选型的理由、从设计到导出的完整操作、代码接入LVGL工程的步骤以及我在实测过程中踩过的坑希望能帮你少走一些弯路。适合谁来读如果你正在用STM32、ESP32或者其他MCU做项目想给设备加一个像样的图形界面但LVGL学得磕磕绊绊或者你已经能跑通LVGL的基础显示但每次画界面都靠手撸代码效率极低再或者你只是听说了LVGL和Anyui这两个名字还没搞清楚它们是干嘛的——那你都可以把这篇看完实操部分直接照着做就行。2. 为什么是Anyui免安装网页版背后的选型逻辑先说结论在“可视化生成LVGL代码”这个细分方向上Anyui不是我见过的唯一选择但它是目前对新手最友好、最没有上手门槛的那一个。我前后用过几款同类工具各有特点下面用我的真实体验做个对比。2.1 主流可视化LVGL工具横向对比工具运行方式学习门槛生成代码质量适合人群手写LVGL代码本地高完全可控进阶开发者、追求极致性能GUI-Guider桌面软件需安装中高已熟悉该类工具链的用户TouchGFX桌面软件需安装依赖特定生态中高高使用特定厂牌芯片的用户Anyui网页版免安装低中上新手、快速原型验证、教学演示这个表格里的信息量其实挺大的。GUI-Guider和TouchGFX都是老牌的桌面工具功能很成熟但问题在于它们各自绑定了一定的生态习惯TouchGFX和特定厂牌的芯片绑定很深GUI-Guider生成代码也要适配对应的图形方案。如果你刚接触嵌入式UI一上来就接触这些工具很容易被它们背后的系统规则搞晕。Anyui则完全不同它只做一件纯粹的事你在网页上画图它给你生成LVGL代码。没有复杂的项目配置没有环境依赖打开浏览器就能开工。2.2 免安装这个卖点藏着一个很实在的需求很多老工程师可能觉得“免安装”算什么优势装个软件几分钟的事。但你要知道很多嵌入式新手本身就是学生或者在公司里用着被限制安装权限的办公电脑。还有不少人是把宿舍的笔记本、公司的台式机混着用的换一台电脑就得重新装一套环境真的很折腾。而网页版只需要一个浏览器账号一登设计稿全在云端随时随地接着画。这个体验放在2024、2025年来看属于是切中了真实痛点。更难得的是Anyui网页版的响应速度相当流畅。我在普通办公网络环境下拖动控件、缩放画布都没有明显延迟感。这说明它的前端交互做得比较扎实不是拿个静态表单糊弄人的那种“网页版”。2.3 五分钟跑通全流程的底气从哪来我在标题里写了“5分钟搞定”这句话不是我拍脑袋随便说的。我实测过首次从打开网页到设计出一个带两个页面、三个控件、两个交互事件的简单界面再到导出代码、拉进模拟器跑起来整个过程确实可以控制在5分钟左右。前提是你已经提前做好了两件事一是有一个能跑通的LVGL模拟器工程二是理解了Anyui的基本操作逻辑。这两个前置条件后面章节会详细展开。说白了Anyui解决的是“UI设计效率和嵌入式工程的衔接”问题。它帮你把最花时间、最容易出错的部分——控件的坐标布局、样式参数、事件绑定——用可视化的方式自动产出了你拿到手的是一份可以直接编译的C代码。省下来的时间你可以去优化业务逻辑、调动画效果、修显示性能而不是浪费在对着屏幕数像素上。3. 三十分钟从零到一Anyui网页版的完整实操流程好前面说了那么多理念层面的东西现在进入真正可以照着做的环节。我以我自己在LVGL 9.x PC模拟器环境下实测的路径为例带大家完整走一遍Anyui设计UI并导出代码的流程。虽然工具本身迭代速度不慢界面细节可能会有变化但底层逻辑大致如此。3.1 打开网页创建你的第一个画布打开浏览器直接搜索Anyui官网进入之后用邮箱注册或者第三方账号登录即可。不需要下载任何客户端不需要配置任何环境变量这一点对初学者来说真的省心。登录进去之后你会看到一个类似“新建项目”的入口。点击创建它会让你选择目标平台和屏幕参数。这里我重点说一下屏幕参数的设置逻辑LVGL的运行目标千差万别从128x64的单色小屏到800x480的彩色TFT都有所以你需要提前知道自己的显示屏分辨率是多少。我测试用的模拟器窗口分辨率设的是480x272这是很多工控手持设备屏幕的经典分辨率所以我在创建画布时填的就是这个尺寸。颜色深度我选了RGB565因为LVGL在低端MCU上最常用的就是16位色深显存占用和渲染速度的平衡点最好。如果你用的是RGB888的屏可以选24位或32位对应的选项但要注意内存占用会成倍上涨。提示如果你是第一次接触LVGL暂时没有硬件屏幕建议直接用PC模拟器先跑。模拟器的屏幕参数可以随意改等UI设计验证通过了再对着硬件的真实参数重新创建画布即可。3.2 认识画布与控件库比想象中直观创建好画布之后你会看到一个典型的“所见即所得”式设计界面。中间是画布区域右侧是属性面板左侧或者顶部则是控件库和许多网页设计工具的布局逻辑很像。Anyui的控件库基本覆盖了LVGL的核心控件类型常见的都有标签Label用来显示文本比如标题、数值、提示信息按钮Button最基本的交互控件支持点击事件仪表盘Meter用于显示速度、温度、电量这类物理量非常实用进度条Bar显示进度或百分比滑块Slider支持用户拖拽调节参数弧形Arc可以做成旋钮式的交互控件图像Image显示图片或图标开关Switch适合做设备开关控制如果你是第一次用建议先拖一个标签和一个按钮出来随便玩一下感受拖拽的流畅度和属性面板的变化。挂着LVGL样式树的那些选项在Anyui里基本都以很直白的方式呈现出来了圆角半径、背景颜色、字体大小、对齐方式、透明度、边框宽度——你调一个属性画布上的效果即时更新这种感觉比自己改代码反复编译痛快太多了。3.3 搭一个真实可用的仪表盘界面空谈功能没意思我们直接设计一个“温湿度监测仪”的主界面来当案例。这个例子兼顾了实用性、设计感和交互逻辑能让你直观感受Anyui的效率。整个界面规划如下顶部放一个标签显示“环境监测 V1.0”作为标题栏左侧放一个仪表盘用来显示温度值右侧放一个仪表盘用来显示湿度值底部放一个按钮文案是“详情”点击后切到第二页第二页放置几个数值型标签和一个返回按钮实际操作时我从控件库拖了两个仪表盘到画布上。然后把第一个仪表盘的“最小值”设为0、“最大值”设为100刻度范围根据测温需求设定再把第二个仪表盘的颜色主题改成蓝色系用来代表湿度。属性面板里每一项改动画布上的预览反馈几乎是实时的这个体验对新手非常友好你不用猜“这个参数改了之后效果是什么”直接看就行。接着拖一个标签到顶部双击改文字为“环境监测”在属性面板里把字体调大对齐方式设为水平居中。再拖一个按钮到底部设置宽度为120像素、高度为40像素文字内容改成“详情”。为了让它看起来不那么呆板我顺手把圆角半径调到了10又给它加了一个浅灰色的阴影效果——这些操作在一开始手写LVGL的时候我可能得花一下午去调试。3.4 事件绑定让界面真正“活”起来UI光有静态外观是没有灵魂的Anyui的亮点之一就是对事件处理做了很直观的封装。以底部的“详情”按钮为例我要实现的效果是点击这个按钮界面切换到第二页。在Anyui里选中这个按钮找到交互/事件设置的区域点击“添加事件”。它会让你选择触发方式一般是点击即“点击触发”然后选择动作类型。不同版本里的选项名称略有差异但大体的逻辑是触发方式 目标动作 目标对象。在这个案例里我选择了“点击触发”事件动作选“页面跳转”或“显示页面”目标对象指向第二页对应的画布。整个过程不需要写一行C代码事件逻辑就记录在设计文件里了。这背后的实现原理是当Anyui导出代码时它会在生成的ui.c或对应的事件回调文件里自动创建好事件处理函数的骨架并把页面切换的调用逻辑填进去。你拿到的代码里会留出用户自定义的填充区域方便你加入自己的业务逻辑——比如跳转前先更新一下显示的数据。注意Anyui生成的事件处理框架解决的是“跳转、切换、更新控件值”这类常见交互。如果你的交互逻辑特别复杂比如多个滑块联动、条件分支判断还是建议在生成的代码基础上手写补充逻辑。工具生成框架、设计者填核心逻辑这是最合理的分工。3.5 预览与导出拿到一份干净可用的代码设计完成后先别急着导出。Anyui一般都有预览模式可以在网页端模拟当前界面的运行状态检查控件布局有没有重叠、文字有没有溢出、按钮点击是否正常响应。我个人的习惯是每设计完一个页面都先预览一轮比导出再编译烧录的反馈循环快得多。确认没问题之后点击“导出”按钮选择目标版本为LVGL 9.x如果你用的是旧版的LVGL 8.x请选择对应的导出选项两者的API有较大差异不匹配会编不过。导出完成后你会得到一个压缩包里面通常包含ui.c/ui.h页面的核心生成代码images.c/images.h嵌入式图片资源数组文件fonts.c/fonts.h如果是默认字体则可以不用其他资源文件按具体需求而定至此Anyui这边的任务就完成了。接下来要做的事就是把这个压缩包里的代码对接进一个能编译的LVGL工程里。4. 代码拿到手之后导出的文件如何对接LVGL工程很多新人会卡在这一步代码导出来了是几个C文件然后呢怎么和自己手上的STM32项目或者PC模拟器工程结合起来别急这部分的流程非常固定照着做就能跑通。4.1 跑通一个LVGL环境模拟器是新手的最佳起点如果你是从零开始我强烈建议先在你自己的电脑上把一个LVGL模拟器工程跑起来再做代码对接。模拟器的意义在于它把硬件显示屏的驱动、触摸驱动全部抛在一旁让你在Windows/Linux/Mac的桌面窗口里就能看到LVGL渲染的完整效果。LVGL官网提供了官方的模拟器工程其中PC模拟器方案是比较主流的选择下载源码、把它接入你的开发环境支持Visual Studio和命令行构建、运行起来后屏幕上会出现一个窗口并在默认背景下显示一些示例控件。这个窗口就是一个“虚拟屏幕”Anyui导出的代码最终就是要和这个“虚拟屏幕”对接。我最初就是在这个阶段理解了一个重要概念LVGL本身并不关心你的UI长什么样它只提供一套对象系统、事件系统、渲染引擎和控件库。UI内容是你通过代码创建出来的控件树。Anyui导出的代码本质上就是替你写好了“创建这棵控件树”的过程。4.2 把导出的文件放进工程目录打开你下载好的LVGL模拟器工程在资源管理器中找到源码本级或者专门管理UI代码的子目录。把上面提到的ui.c、ui.h、images.c等文件放入这个目录。然后在工程文件所在的项目配置里把新增的C文件加入构建列表。以CMake为例只需要在对应位置的add_executable里追加源文件或者利用file(GLOB...)让CMake自动扫描目录下的所有源文件这样以后新增文件就不用频繁改工程文件了。用Makefile或者Keil工程的朋友思路是一致的保证这些文件参与到编译过程中。头文件的搜索路径也要检查一下。如果你把ui.h放到了ui子目录那代码里#include ui.h就需要能定位到这个目录。通常在工程配置里的头文件路径列表Include Paths里加上这个子目录即可。4.3 初始化与调用顺序决定成败你把UI文件编译进去只是第一步最关键的是在main函数里正确初始化和调用。我见过最多的新人踩坑就是直接把ui_init()塞进了main结果屏幕黑屏或者疯狂硬错误。一个典型的LVGL主循环长这样#include lvgl.h #include ui.h int main(void) { // 1. 初始化LVGL核心库 lv_init(); // 2. 初始化显示驱动与缓冲区 lv_display_t *disp; static lv_color_t buf1[480 * 100]; disp lv_display_create(480, 272); lv_display_set_buffers(disp, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL); // 这里需要根据你的模拟器接入实际的flush接口 // 3. 初始化UI ui_init(); // 4. 进入主循环模拟器环境下可以直接用while(1) while (1) { lv_timer_handler(); lv_tick_inc(5); } return 0; }这段代码的顺序是非常讲究的lv_init()先初始化图形库的核心然后创建显示设备并设置显示缓冲区和刷新接口做好这两步之后才能调用ui_init()去创建界面上的每个控件最后才进入周期性的定时器循环让LVGL持续地处理事件、刷新屏幕。如果你把ui_init()放在lv_init()之前LVGL的对象系统还没就绪直接创建控件必然奔溃。如果你忘记调lv_timer_handler()你会发现界面只会亮一下然后就不响应了因为LVGL的任务调度没跑起来。这套组合拳的逻辑理解了就再也不会错。提示在STM32等真实硬件上lv_tick_inc()的时基建议放到定时器中断里调用保证LVGL的时间调度足够精确。在PC模拟器上则可以直接在主循环调用或者用系统API获取毫秒时间戳来驱动。4.4 字体、图像资源与内存对齐问题运行过程中还有两个容易被忽略但极其重要的细节。第一是图像资源。Anyui导出的图片通常是C语言数组里面存的是RGB565或RGB888格式的像素数据。这些数组会占用编译后的Flash空间运行时如果LVGL需要直接操作这些数组建议在编译选项中给它们加上适当的对齐属性比如LV_ATTRIBUTE_MEM_ALIGN这样能保证LVGL在进行像素操作时不会因为地址不对齐而出现异常。第二是内存分配。LVGL默认使用自己的内存池或者调用了malloc。如果你的MCU内存很小或者UI里用了很多大尺寸图片初始化的瞬间可能出现分配失败导致创建控件失败。解决思路是先确认你的堆空间够不够大其次可以使用LVGL自带的内存分析工具查看内存水位。我在一款RAM只有64KB的板子上就遇到过“UI初始化到一半就静默停止”的问题最后查出来是内存分配失败被LVGL吞掉了报错信息只能无奈加大堆空间并精简了图片资源。5. 实测中踩过的坑布局错位、字体缺失与资源加载问题这一章我尽量还原我在实际使用Anyui对接LVGL过程中遇到过的真实问题包括问题现象、排查链路和最终的解决办法。这些问题很有代表性新人在前期大概率会碰到至少一两个。5.1 布局错位同样都在PC模拟器上为什么看起来不一样在Anyui网页画布里界面是完美的居中对齐、间距均匀但把导出代码放进模拟器运行后控件位置整体往左上角偏移或者某些控件重叠在一起。排查链路是这样的我先确认了画布尺寸和模拟器窗口分辨率完全一致——这确实是最容易踩的原因模型和实际不一致如果画布设的是320x240而模拟器跑的是480x272控件布局必然错位。确认两者一致后问题依旧于是我接着怀疑是不是某些父容器的样式没有正确导出。最后定位到根因我在Anyui里给一个页面容器设置了flex布局或者grid布局这种布局属性在页面上看起来是生效的但Anyui导出的代码里需要在容器初始化之后手动调用一次lv_obj_update_layout()确保布局引擎在其他控件创建完成后重新计算位置。加上这一行调用之后整个界面的布局和网页预览就完全一致了。5.2 中文字体缺失界面上的汉字全部变成方框这个坑可以说是每个用LVGL做中文界面的开发者都躲不过去的。在Anyui里我明明设置了一个标签的文字为“环境监测”导出后在模拟器里一跑这三个字全变成了豆腐块一样的方框。原因非常明确LVGL默认自带的字体lv_font_unscii_8这类是不包含中文字符集的它只有基本ASCII字符。要用中文你必须指定一个包含中文字形的字体文件。Anyui的字体处理逻辑一般是你可以在它的“字体”设置选项里导入自定义ttf字体文件它会在导出时把字体文件自动转成LVGL能识别的字体数组文件加载在固件里。但如果你是在模拟器里做测试又不想每次生成的字体数组都占很大体积有一个变通方案用LVGL官网教程里的“在线字体转换工具”手动生成一个包含特定汉字的bin或c文件然后根据LVGL 9.x的字体加载接口动态加载。缺点是比较繁琐优点是体积小、可控性强。我的建议是正式项目直接用Anyui内置的自定义字体导入功能一次性配置好后面加新文字都很省心。5.3 图片花屏与颜色空间不匹配我刚开始接自己的项目图片时遇到过图片显示出来颜色完全不对整个画面泛红或者发绿看起来根本不像原图。排查到最后发现是颜色格式不匹配我在Anyui里导入图片时它按照RGB565格式导出了像素数组但我的模拟器显示驱动或者屏幕本身工作在RGB888模式下数据格式不对颜色自然全乱。解决办法也简单在Anyui的图片属性面板里把颜色格式改成和你的目标屏幕一致。如果你用的是RGB565屏就导出RGB565格式如果屏幕支持RGB888就导出RGB888。还有一点是在宿主机上做颜色反转试验时发现有些屏幕的红色和蓝色通道物理上是交换的这种情况就得用LVGL的颜色交换接口或者自己在驱动层做通道重排。5.4 刷新率上不去控件越多画面越发飘当界面里的控件数量超过二十个或者有大量带阴影、渐变的容器时在模拟器上能明显感觉到渲染帧率下降拖拽窗口时画面会撕裂。在低性能MCU上这个问题会更严重。这个问题的本质是LVGL渲染每个像素点都要经过软件混合计算。控件样式越复杂像素覆盖量越大CPU负载越高。优化思路有几条把不需要动态变化的区域设置为lv_obj_set_style_opa(obj, LV_OPA_COVER)减少透明通道的混合计算对图片资源尽量压缩尺寸不要在44寸的屏幕区域贴一张原本该只在10寸区域显示的图还有就是把LVGL的部分渲染区域改成LV_DISPLAY_RENDER_MODE_DIRECT模式利用整块帧缓冲提高刷新一致性。我在实际项目里试过一个非常给力的优化将UI页面拆分成多个子页面只在需要时创建页面控件离开时销毁或隐藏。虽然这样增加了一些页面状态管理的代码量但内存占用和渲染压力都明显下降了。在内存只有几百KB的目标板子上这个取舍非常值。6. 把工具用顺手之后一些关于工作流的真心建议说实话Anyui这类工具刚出现时我也持怀疑态度——总觉得可视化工具生成的代码是“玩具代码”和手写代码没法比。但用了这段时间我修正了自己的看法它生成的是“标准的LVGL代码”核心结构没有硬伤在一些细节设计上甚至比新手手写更规范。它最大的价值不在于替你写了多少行代码而在于把“界面设计”和“业务逻辑”这两个不同节奏的事情分开处理了。设计界面的时候你关注的是布局是否美观、交互是否自然、配色是否舒服这些需要快速迭代可能一上午要调整十几个版本。如果这个阶段靠手写代码改一个控件位置就要重新编译烧录效率太低了。而Anyui帮你把这个阶段的速度提升到了“网页刷新”的水平。等设计定稿了导出的代码再进入你的嵌入式工程你去填充真正的业务逻辑——读取传感器、控制电机、处理通信协议——这时候每一行代码的价值都比拖拽一个控件高得多。根据我个人经验我目前的工作流是这样原型验证阶段一律用Anyui快速出界面跑通交互逻辑进入正式产品阶段对界面性能有苛刻要求的部分会手动微调导出的代码加入UI动效和状态机的精细控制再往后如果设计变更频繁我甚至会把设计稿和代码的对应关系做成一份文档方便团队成员共同维护。这个流程最后要提醒一句Anyui再方便它也只是画界面代码的工具千万不要把它当成“学了它就不用学LVGL”的借口。LVGL的对象模型、事件机制、渲染原理、内存管理这些东西即使你全部用可视化工具生成代码也需要知道基本的那一套。因为只要你是做嵌入式的总会遇到工具生成不了的特殊需求那时候真正救你的还是你对LVGL本身的理解。先把Anyui当作跳板快速体验嵌入式UI开发的完整链路然后深入底层去搞懂它生成的每一段代码是什么意思——这条路我觉得是新手最平滑、最有成就感的一条路。
返回列表