MicroUI 轻量级 GUI 库使用指南
概述
MicroUI 是一个极简的即时模式 GUI 库,专为嵌入式系统和轻量级应用设计。它采用纯 C 语言编写,不依赖任何外部库,非常适合资源受限的环境。本文将详细介绍 MicroUI 的核心概念和使用方法。
基础使用流程
MicroUI 采用典型的即时模式 GUI 工作流程:
-
初始化上下文:
mu_Context *ctx = malloc(sizeof(mu_Context)); mu_init(ctx); -
设置文本测量回调(必须实现):
ctx->text_width = your_text_width_function; ctx->text_height = your_text_height_function; -
主循环结构:
while (running) { // 1. 处理输入事件 mu_input_mousemove(ctx, mouse_x, mouse_y); // 其他输入处理... // 2. 开始UI帧 mu_begin(ctx); // 3. 构建UI界面 if (mu_begin_window(ctx, "窗口标题", rect)) { // UI控件代码... mu_end_window(ctx); } // 4. 结束UI帧 mu_end(ctx); // 5. 渲染命令处理 mu_Command *cmd = NULL; while (mu_next_command(ctx, &cmd)) { // 根据cmd->type处理不同渲染命令 } }
窗口系统
MicroUI 的窗口管理非常轻量:
- 使用
mu_begin_window()和mu_end_window()创建窗口 - 窗口可以嵌套,适合实现上下文菜单等复杂交互
- 窗口自动处理布局和滚动条
示例窗口代码:
if (mu_begin_window(ctx, "设置面板", mu_rect(100, 100, 300, 400))) {
mu_label(ctx, "音量设置:");
mu_slider(ctx, &volume, 0, 100);
if (mu_button(ctx, "保存")) {
save_settings();
}
mu_end_window(ctx);
}
布局系统详解
MicroUI 采用基于行和列的灵活布局系统:
基本行布局
// 创建一行3个元素,宽度分别为90,100,100,高度自动
mu_layout_row(ctx, 3, (int[]) { 90, 100, 100 }, 0);
mu_button(ctx, "确定");
mu_checkbox(ctx, "启用", &enabled);
mu_slider(ctx, &value, 0, 10);
相对布局
使用负值实现动态调整的布局:
// 左侧固定30px,中间自适应,右侧固定宽度
mu_layout_row(ctx, 3, (int[]) { 30, -1, 80 }, 0);
列布局
mu_layout_begin_column(ctx);
{
mu_layout_row(ctx, 1, (int[]) { -1 }, 0);
mu_label(ctx, "列内元素1");
mu_label(ctx, "列内元素2");
}
mu_layout_end_column(ctx);
控件交互处理
所有交互控件都会返回一个结果标志位:
// 按钮点击检测
if (mu_button(ctx, "点击我")) {
printf("按钮被点击\n");
}
// 滑块值变化检测
if (mu_slider(ctx, &value, 0, 100) & MU_RES_CHANGE) {
printf("值改变为: %d\n", value);
}
处理重复ID问题
当有多个相同标签的控件时,需要使用ID堆栈:
for (int i = 0; i < 5; i++) {
mu_push_id(ctx, &i, sizeof(i));
if (mu_button(ctx, "删除")) {
delete_item(i);
}
mu_pop_id(ctx);
}
样式定制
MicroUI 提供两种级别的样式定制:
-
基础样式调整:
ctx->style->colors[MU_COLOR_BUTTON] = mu_color(255, 0, 0, 255); ctx->style->padding = 10; // 设置内边距 -
高级绘制控制: 通过重写
draw_frame回调实现完全自定义的控件外观。
自定义控件开发
MicroUI 公开了内部控件开发接口,允许创建自定义控件。一个典型控件应包含:
- 获取唯一ID
- 从布局系统获取位置
- 处理交互状态
- 绘制控件
示例自定义计数器控件:
int custom_counter(mu_Context *ctx, int *value) {
// 1. 获取控件ID
mu_Id id = mu_get_id(ctx, value, sizeof(value));
// 2. 获取布局矩形
mu_Rect rect = mu_layout_next(ctx);
// 3. 更新交互状态
mu_update_control(ctx, id, rect, 0);
// 4. 处理交互
int res = 0;
if (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->focus == id) {
(*value)++;
res |= MU_RES_CHANGE;
}
// 5. 绘制控件
char buf[32];
sprintf(buf, "计数: %d", *value);
mu_draw_control_frame(ctx, id, rect, MU_COLOR_BUTTON, 0);
mu_draw_control_text(ctx, buf, rect, MU_COLOR_TEXT, MU_OPT_ALIGNCENTER);
return res;
}
性能优化建议
- 避免频繁的内存分配,复用缓冲区
- 对于静态界面,考虑缓存渲染结果
- 合理使用布局系统,减少不必要的重排
- 在资源受限的设备上,简化样式和绘制逻辑
MicroUI 的设计哲学是"够用即可",它提供了构建基本用户界面所需的核心功能,同时保持了极小的代码体积和内存占用。通过理解其设计理念和灵活运用各种特性,开发者可以在各种环境中创建出高效的用户界面。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



