uCGUIBulider 4.0.0.0:可视化拖拽生成uC/GUI界面代码
简介uCGUIBulider 4.0.0.0是一套面向嵌入式系统开发者的图形用户界面设计工具与uCGUI轻量级图形库配套使用旨在简化微控制器上复杂UI的构建流程。压缩包体积仅7.87MB包含430个文件其中以C/C头文件、静态库、可执行程序及批处理脚本为主既有完整的源码工程与工程文件也有编译好的工具程序、依赖动态库和VC2008环境配置脚本支持在Windows 8 64位系统上直接展开使用。借助可视化拖放控件、属性设置和实时预览开发者能够快速完成智能家居、车载显示、医疗仪器等场景的界面设计并自动生成可移植的底层代码显著减少手工编码工作量。资源已有178人浏览学习适合正在学习uCGUI框架或需要为嵌入式项目快速搭建UI界面的工程师参考。1. uCGUIBulider4.0.0.0可视化拖拽生成uC/GUI界面的落地工具uCGUIBulider 4.0.0.0 是面向 uC/GUI 图形库的可视化界面设计工具很多人在网上搜uCGUIBuilder或uC-GUI 界面设计器指的都是这一套东西。它解决一个很现实的嵌入式问题屏幕没多大菜单却有七八层每个界面都手写窗口创建和回调的话改一次布局等于重写一遍逻辑。用这个工具拖控件、设属性、点生成C 代码就直接出来挂进工程就能编译。适合用裸机或 RTOS 做屏显项目、被硬编码坐标折磨的单片机工程师也适合刚接触 uC/GUI 想快速看到界面的初学者。2. 先认识界面与工作流四个面板和三个固定动作2.1 打开工具先分清四个区域我第一次打开 uCGUIBulider 时把它当成普通画图工具拖了半个小时后发现控件位置完全对不上。后来把它拆开看其实它和大多数 GUI 编辑器一样主窗口由四块组成左侧控件工具箱、中间画布、右侧属性面板、底部工程资源窗口。控件工具箱里是常用的基础控件按钮、文本、复选框、滑条、进度条、下拉框对应 uC/GUI 里的 BUTTON、TEXT、CHECKBOX、SLIDER、PROGRESSBAR、DROPDOWN 控件类。把控件拖到画布上右侧属性面板就会同步显示它的坐标、宽高、控件 ID、字体、对齐方式。底部工程资源窗口管理整个工程的对话框、字体、位图、回调函数像一棵资源树生成代码时也是从这棵树上挑资源打包。清楚四个区域之后整个使用流程固定成三个动作往画布放控件、在属性面板改参数、在工程窗口点生成。后面无论做多复杂的菜单本质都是这三步的循环。uCGUIBulider 的价值不在于帮你画一个漂亮界面而在于把界面长什么样和代码怎么写绑在一起改布局就等于改数组逻辑和表现能分开迭代。2.2 分辨率、深度与颜色格式画布和屏幕必须对齐动手画之前有一组参数要先确认屏幕分辨率、位深、颜色格式。工具允许在工程属性里设置目标屏幕的宽和高单位是像素常见的有 320x240、800x480 这些。分辨率设错最直接的影响是画布尺寸和真实屏幕不一致控件放上去后要么超出屏幕边界被裁掉要么只占屏幕一角。这里最容易忽略的是颜色格式。uC/GUI 的底层是 LCD 驱动适配层支持 RGB565、RGB888、BGR565 等。如果你的屏是 RGB565生成的代码会把颜色值打包成两个字节写入显存时高低字节顺序必须和屏模组匹配。工程属性里选错界面整体偏色红色变蓝色、蓝色变绿色排查起来非常费劲。常见做法是先看 LCD 驱动例程里的初始化配置照着它选不要凭着对屏规格书的印象填。位深对应 uC/GUI 的 LCD_BITSPERPIXEL 宏决定颜色字节数和后面图片、字体转换时的像素对齐。选错的话图片显示会花屏或错位尤其当你在同一个工程里同时用图片和字体时转换工具的像素格式和工程属性不一致运行时的颜色数据会被重新解释显示结果完全不可预期。我的经验是先读一遍 LCD 例程里的配置再回工具里填这一项填错了后面返工成本最高。2.3 坐标系与对话框一个对话框就是一块独立画布uCGUIBulider 里的界面本质上是 uC/GUI 的对话框。对话框是一个独立窗口所有控件都挂在它上面。画布的白色区域就是一个对话框控件坐标是相对对话框左上角的不是屏幕绝对坐标。这个设计意味着对话框移动时控件不会跟着自动重排除非你在初始化回调里动态计算位置。这个特性影响两点一是你框选全部控件整体拖动时它们的相对位置保持不变但绝对坐标整体偏移这个偏移会原样写进生成代码二是如果你的界面需要居中显示不能靠修改对话框创建坐标完成只能在 WM_INIT_DIALOG 里按屏幕分辨率重新算一遍控件偏移。操作上很简单从工具箱点中一个文本控件在画布上拖一个区域属性面板里就能改文本内容、字体、对齐方式。先不改直接点 Generate工程目录下就有了带初始化数组和回调函数骨架的 C 文件。一行代码没写一个能编译的对话框已经出来了。很多人第一次用会被这个速度惊到这也是这个工具至今还在嵌入式 GUI 领域被不断下载的原因。3. 从画布到工程生成代码的结构、编译集成与参数调整3.1 点击 Generate 之后发生了什么点击 Generate 之后工具会根据当前对话框生成两个关键文件对话框资源文件、回调与创建函数文件。把这两个文件加进工程主程序里调用创建函数就能把界面弹出来。下面是一个简单对话框生成结果的关键片段和 uCGUIBulider 4.0.0.0 默认输出风格一致static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] { { TEXT_CreateIndirect, txtTitle, ID_TEXT_TITLE, 0, 0, 0, 240, 30, 0, 0, 0, 0, 0 }, { BUTTON_CreateIndirect, btnOk, ID_BUTTON_OK, 10, 50, 100, 30, 0, 0, 0, 0, 0, 0 }, { BUTTON_CreateIndirect, btnCancel, ID_BUTTON_CANCEL, 130, 50, 100, 30, 0, 0, 0, 0, 0, 0 }, }; static void _cbDialog(WM_MESSAGE * pMsg) { switch (pMsg-MsgId) { case WM_INIT_DIALOG: TEXT_SetText(WM_GetDialogItem(pMsg-hWin, ID_TEXT_TITLE), System Info); break; case WM_NOTIFY_PARENT: if (pMsg-Data.v WM_NOTIFICATION_RELEASED) { int Id WM_GetId(pMsg-hWinSrc); if (Id ID_BUTTON_OK) { /* 用户点击了 OK */ } else if (Id ID_BUTTON_CANCEL) { GUI_EndDialog(pMsg-hWin, 0); } } break; default: WM_DefaultProc(pMsg); } }这段代码的逻辑是_aDialogCreate 数组描述对话框里每个控件的创建信息_cbDialog 是对话框的回调函数处理初始化消息和控件通知。两段合在一起就是 uC/GUI 对话框运行时的全部骨架。工具把这两个部分生成好你只需要在回调里填业务逻辑。参数说明TEXT_CreateIndirect 和 BUTTON_CreateIndirect 是控件间接创建函数参数依次是控件类型、控件名、控件 ID、x、y、宽、高、附加标志、附加参数、字体 ID、字体颜色、背景色。其中第 4、5 个参数是坐标第 6 个是宽度、第 7 个是高度单位都是像素0 表示不设置不设置的值会走控件默认属性。控件名是字符串标签运行时只作为调试标识不影响逻辑但建议保持和功能一致。3.2 把生成代码接进工程文件名、头文件与初始化生成文件默认有固定命名风格常见的像 DIALOG_1.c、DIALOG_1.h 这种。你需要做三件事把 .c 文件加进编译器工程、把 .h 文件所在路径加进包含目录、在 main 里 include 后调用创建函数。创建函数的命名一般和对话框名相关比如 CreateDialog1(void)。我一般会把生成代码和驱动代码分开目录放因为工具一旦重新生成会覆盖原文件。如果手改过生成文件下次点生成改动会直接消失这一点后面避坑章节会专门讲。头文件里通常还包含控件 ID 的枚举比如 ID_TEXT_TITLE、ID_BUTTON_OK回调里依赖这些 ID 做分支不到万不得已不要改动。常见集成顺序是把 DIALOG_1.c 复制进工程源码目录。在 main 函数所在文件 include DIALOG_1.h。在图形库初始化之后调用 CreateDialog1()。根据界面模式选择消息循环方式模态界面进 GUI_ExecDialogCreate非模态界面留在 WM_CreateDialogBox 管理。有一点容易混淆WM_CreateDialogBox 和 GUI_ExecDialogCreate 的区别。前者创建后立即返回调用线程可以继续做别的事界面生命周期交给窗口管理器后者会进入对话框消息循环直到对话框被关闭才返回。如果你的界面是模态窗口用 GUI_ExecDialogCreate 最简单如果只是作为主界面的一部分用 WM_CreateDialogBox 更合适这也是 4.0.0.0 生成代码里默认不带 Exec 的原因。3.3 控件属性面板里的几个关键参数属性面板里参数很多但真正影响行为的是少数几个。控件 ID 决定回调里能区分哪个控件被操作建议按功能命名而不是按序号命名比如 ID_BUTTON_SAVE、ID_BUTTON_CANCEL维护时一眼能看懂。Tab 顺序决定键盘焦点在控件间切换的次序在工具里可以用列表调整做键盘导航类产品时必须关注普通触摸屏界面可以不管。字体参数是一个下拉选择默认是 GUI_FONT_DEFAULT 这类西文字体。想要中文字体需要先在工程资源里添加并生成字体文件这一块的坑集中在第 4 章。对齐方式分水平左中右和垂直顶中底生成代码对应 TEXT_SetTextAlign 的内部实现。还有一类控件特有的附加标志比如 BUTTON 的 GUI_BUTTON_NOTIFY、CHECKBOX 的 GUI_CHECKBOX_NOTIFY控制控件是否向父窗口发送通知消息。默认很多控件是不发通知的如果发现回调里始终收不到某个控件的 WM_NOTIFY_PARENT第一反应应该是检查这个标志而不是怀疑回调写错了。3.4 与 uC/GUI 版本匹配API 和回调风格的差异uCGUIBulider 4.0.0.0 生成的代码主要面向特定 API 阶段的 uC/GUI。如果你手头的图形库版本较老或较新有些函数可能改名消息参数的取法也可能有差异。比如部分版本里 WM_NOTIFY_PARENT 的附加数据通过 pMsg-Data.v 取另一部分版本则把通知细节放进 pMsg-Data.p 指向的结构体里再取。遇到这类差异我的处理方式不是改生成器的输出而是在自己工程里加一层适配。例如回调里统一通过 WM_GetId 拿控件 ID不依赖用户自定义消息的附加字段初始化统一在 WM_INIT_DIALOG 里完成不在创建数组里塞太多自定义参数。这样工具重新生成代码后适配层不用跟着变工程照常编译。4. 字体与图片资源转换中文显示和位图导入的几个硬门槛4.1 为什么中文是硬门槛uC/GUI 本身不自带中文字库默认字体只覆盖西文字符集直接往 Text 控件里写中文运行时显示的是一堆空心方块。原因是 uC/GUI 的字体系统基于 Unicode 编码映射字形数据字体文件里没收录的字符无法显示。所以要让界面显示中文必须先准备一个包含所需字符的字体文件再用配套的字体转换工具生成 uC/GUI 可识别的 C 代码字体。这一步是 uCGUIBulider 工作流里最容易被低估的部分。很多人控件拖好了、代码生成完了一看中文全是方块到处找补丁实际上问题出在工程里根本没挂中文字体资源。工具本身不负责帮你打包字库它只负责在控件属性里引用你已经转换好的字体变量。4.2 用字体转换工具生成字体 C 文件字体转换工具是独立运行的不集成在 uCGUIBulider 主界面里。常见流程是加载 TTF 或 TTC 字体文件选择目标字符表设置字号和抗锯齿选项导出一个 C 文件。中文字体字符量大生成的文件体积比西文字体大很多转换时参数设置直接影响代码体积和显示效果。工具导出时有一组参数我按经验整理了建议值参数作用建议字号决定字形点阵大小按设计稿定别小于 12抗锯齿是否生成灰阶过渡小屏用 4 级灰阶字符范围包含的 Unicode 码位只放用得到的字符编码格式内部映射表宽度保持默认与主工程一致像素格式颜色位深对齐必须与 LCD 位深一致导出后的字体文件是一个 C 数组包含字形位图数据和字符映射索引。把 C 文件加进工程后还要回 uCGUIBulider 里刷新字体列表新字体才会出现在控件属性的字体下拉框里。有的版本需要手动把字体变量名填进文本控件的字体字段不会自动识别。中文字体这块没有捷径字符表选多了 Flash 吃紧选少了生僻字显示方块属于典型的平衡题。4.3 位图导入的两种方式图片资源的处理路径和字体类似。uC/GUI 支持把 BMP 直接转换成 C 数组也支持从文件系统里加载 PNG、JPEG。uCGUIBulider 4.0.0.0 里常配合位图转换工具使用把 BMP 转成 C 文件形式存储生成的是一个包含图像数据和格式信息的 C 数组。转换参数里最重要的是像素格式和压缩选项。像素格式必须和 LCD 一致比如 LCD_RGB565 对应转换器里的 RGB565 输出不一致时显示会花屏。压缩选项一般选 RLE 压缩能减少图片数据体积代价是显示时 CPU 要做解压处理速度稍慢。如果图片是静态图标或背景推荐 RLE如果是频繁变化的动态区域用不压缩反而更省 CPU因为省掉了每次显示前的解压耗时。生成的位图 C 数组会定义一个 IMAGE 结构变量引用时需要把结构变量名填给控件的 Image 属性。常见错误是只把数组名填了进去实际上应该填 IMAGE 结构变量名数组名是给结构体内部使用的控件读取的是结构体。这个错误很隐蔽编译不报错运行时图片直接不显示或显示一条黑带。4.4 外部存储与流位图当界面里大量使用图片、照片级背景或者大字号字体时C 数组方案会把整个程序镜像撑得很大。硬件 Flash 放得下的时候问题不大但芯片 Flash 紧张时就要考虑外部存储方案。uC/GUI 提供流位图机制图片数据以压缩文件形式放在外部 Flash显示时通过 GUI_JPEG_Draw、GUI_PNG_Draw 这类带 _GetData 接口的回调按需读取。uCGUIBulider 本身生成代码时不会自动生成文件系统读取逻辑你需要自己写 _GetData 回调返回一帧数据给图形库。这个方案的边界在控制器必须能访问外部存储且访问速度不能太慢。如果外部 Flash 挂在低速 GPIO 模拟 SPI 上整屏重绘时会明显感觉刷新卡顿尤其在菜单切换瞬间。我的经验是图片类资源少于十张时优先用 C 数组省事且稳定超过这个数量再考虑流位图。中等规模工程里字体和图片加在一起的体积经常比代码本身还大这个判断能帮你省下不少调优时间。5. 避坑指南坐标、回调、编码与数据体积的五个坑5.1 控件坐标必须在对话框范围内现象生成代码编译通过上电后界面上某些控件就是看不到怎么找都找不到。原因uCGUIBulider 的画布可以画出对话框窗口大小也可以把控件拖到对话框外的画布区域。拖出去之后工具依然生成合法的坐标值编译器不报错因为坐标在运行时才被控件创建函数使用。控件创建时坐标是负数或超过分辨率上限uC/GUI 在创建阶段不做越界检查只是不回显。解决在点生成之前打开工程资源窗口逐个检查控件坐标是否落在对话框矩形内。也可以把对话框整体放大一点再框选全部控件拖回画布可视区域。最保险的做法是生成后搜索 x、y 小于 0 的初始化行手动修正别等到上板再排查。5.2 控件通知收不到附加标志没开现象回调里写了按钮的事件处理但按钮按下去之后函数不执行。原因BUTTON 控件默认不发送 WM_NOTIFICATION_RELEASED 通知除非创建时带上了 GUI_BUTTON_NOTIFY 附加标志。uCGUIBulider 属性面板里这一项如果没勾选生成代码就是不带通知的回调自然什么都没有收到。解决选中按钮在属性面板里勾选 Notify 相关标志重新生成代码。注意重新生成后要把新文件替换进工程而不是继续用旧文件调试否则你会怀疑是自己代码写错查半天还在原地。5.3 中文显示方块或乱码字体映射没生效现象字体转换 C 文件已经加进工程但 Text 控件里的中文还是不显示有些字显示、有些字是方块。原因一类原因是字体转换时字符表不全生僻字或标点没在表里另一类原因是 uCGUIBulider 里文本控件的字体属性没有指向转换后的字体变量还在用默认西文字体还有一类是源文件编码和字体映射表编码不一致编辑器把中文按 GB2312 存盘字体映射按 Unicode 码位生成两边对不上。解决转换字体前先确定用到的字符集宁可多选几十个常用标点。给文本控件指定字体时直接手动写入转换出来的字体变量名别依赖自动选择。源文件统一用 UTF-8 编码保存并在工程里保持一致。这一条属于翻车概率最高的坑遇到中文问题先按这三条排查能解决九成。5.4 重新生成把手工改动覆盖了现象生成代码后手动在回调里加了一段逻辑后来改了界面布局重新生成发现之前加的代码全没了。原因工具的设计就是整文件覆盖。uCGUIBulider 不保留用户对生成文件的手工修改也没有合并差异的选项重新生成等于把整个文件替换成新版本。解决把需要维护的业务逻辑从生成文件里拆出去。回调里的具体业务放到独立 C 文件的独立函数中生成文件只保留调用入口或者每次手工改动前先复制一份备份。常见做法是生成后先备份再修改重新生成后比对差异把旧文件里保留的逻辑手工搬回来。提示我现在的习惯是生成代码之后先复制一份到 backup 目录再开始改。工具重新生成只当它是一份新图纸改动永远在备份和业务层里做。5.5 图片导入后 RAM 暴涨现象加了几张大图片后程序镜像明显变大运行时的 RAM 占用也上升界面偶尔还闪烁。原因默认的位图 C 数组方案会把像素数据存放在只读区但如果图片通过 GUI_BITMAP 结构被创建成动态对象或者运行时被复制到 RAM 缓冲区作为屏上缓存RAM 占用会成倍增长。像素格式不对时图形库会做转换缓冲也会额外占用 RAM。解决静态图标用 C 数组大图片用流位图。在资源窗口里查看图片位深确保与 LCD 一致避免运行时转换。如果硬件有条件把显存 DMA 和多帧缓冲放到外部 RAM别和图片缓冲区挤同一块内存。RAM 暴涨这条通常是压死骆驼的最后一根稻草提前规划好位深和存储方式能省掉很多调优时间。6. 最后一步在模拟器里验证生成结果再上板6.1 把生成代码放进模拟器工程生成代码能编译只能算走完一半界面实际长什么样、控件交互是否正常最好先在一套模拟器里跑一遍。uC/GUI 的配套模拟器工程支持在 PC 上编译运行把生成的 C 文件加进去替换掉示例对话框设置一个合适的屏幕分辨率就能在电脑上看到完整的界面交互效果。这个环节能提前发现绝大多数坐标偏移、字体缺失和颜色格式问题比上板后一个个查省太多时间。具体做法是先确认模拟器工程的 LCD 配置和目标屏一致包括分辨率、位深、颜色格式这三项不一致时模拟结果没有参考价值。然后把生成文件加进工程在模拟器主文件里调用创建函数编译运行。第一次跑通常会发现字体不对、控件位置偏出边界等问题这些在模拟器里改起来比在板子上快得多。6.2 多语言界面的一个实用技巧uCGUIBulider 生成的文本控件默认把字符串写死在初始化数组里多语言切换时要全部换文字会比较麻烦。一个实用的做法是文本控件的内容不在生成文件里写死而是在 WM_INIT_DIALOG 里根据当前语言查表设置。这样生成文件只保留控件结构运行时按语言索引填充字符串切换语言时只需要刷新界面文本不需要重新生成代码。配合模拟器验证也很方便在模拟器里切换语言参数跑一遍所有对话框检查是否有文本溢出、对齐错位、字体缺失。这个习惯帮我解决了不少界面问题尤其是阿拉伯语等排版方向特殊的语言在模拟器里能直观看到对齐结果。从那以后我每次生成完都会在模拟器里跑一遍界面确认坐标、字体、颜色三样都正常才交给硬件联调。希望帮到你。本文还有配套的精品资源点击获取