Rust UI组件库re_ui的使用:轻量级、模块化与跨平台的用户界面开发解决方案

re_ui

属于 rerun 系列 crate 的一部分。

Rerun GUI 主题和辅助工具,基于 egui 构建。

定义了 Rerun Viewer 的主题,并包含构建某些 UI 元素的辅助工具。

还包含我们的字体和图标。

安装

在您的项目目录中运行以下 Cargo 命令:

cargo add re_ui

或者将以下行添加到您的 Cargo.toml:

re_ui = "0.24.1"

完整示例代码

以下是一个使用 re_ui 创建简单 GUI 应用的完整示例:

use eframe::egui;
use re_ui::ReUi;

fn main() -> Result<(), eframe::Error> {
    let options = eframe::NativeOptions {
        initial_window_size: Some(egui::vec2(400.0, 300.0)),
        ..Default::default()
    };
    
    eframe::run_native(
        "re_ui 示例应用",
        options,
        Box::new(|cc| {
            // 应用 re_ui 主题
            ReUi::setup(&cc.egui_ctx);
            
            Ok(Box::new(MyApp::default()))
        }),
    )
}

#[derive(Default)]
struct MyApp;

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("欢迎使用 re_ui");
            
            ui.add_space(20.0);
            
            // 使用 re_ui 的样式组件
            if ui.button("点击我").clicked() {
                println!("按钮被点击!");
            }
            
            ui.add_space(10.0);
            
            // 添加一些文本输入
            ui.label("输入一些文本:");
            ui.text_edit_singleline(&mut String::new());
            
            ui.add_space(20.0);
            
            // 使用分隔线
            ui.separator();
            
            ui.label("这是一个使用 re_ui 主题的简单示例应用");
        });
    }
}

使用说明

要使用 re_ui,首先需要在您的 Cargo.toml 中添加依赖:

[dependencies]
re_ui = "0.24.1"
eframe = "0.25"  # 用于创建桌面应用
egui = "0.25"    # GUI 库

然后在您的应用启动时设置 re_ui 主题:

use re_ui::ReUi;

// 在应用初始化时
ReUi::setup(&egui_ctx);

这样您的应用就会使用 Rerun Viewer 的主题样式,包括颜色、字体和图标等。

许可证

MIT OR Apache-2.0 AND OFL-1.1

扩展完整示例代码

基于提供的示例,以下是一个更完整的 re_ui 应用示例:

use eframe::egui;
use re_ui::ReUi;

fn main() -> Result<(), eframe::Error> {
    // 配置窗口选项
    let options = eframe::NativeOptions {
        initial_window_size: Some(egui::vec2(600.0, 400.0)),
        min_window_size: Some(egui::vec2(400.0, 300.0)),
        ..Default::default()
    };
    
    // 启动应用
    eframe::run_native(
        "re_ui 完整示例应用",
        options,
        Box::new(|cc| {
            // 获取 egui 上下文
            let egui_ctx = &cc.egui_ctx;
            
            // 应用 re_ui 主题和样式
            ReUi::setup(egui_ctx);
            
            // 设置视觉样式
            egui_ctx.set_visuals(egui::Visuals::dark());
            
            // 返回应用实例
            Ok(Box::new(MyApp::new()))
        }),
    )
}

struct MyApp {
    text_input: String,
    click_count: u32,
    show_advanced: bool,
}

impl MyApp {
    fn new() -> Self {
        Self {
            text_input: String::new(),
            click_count: 0,
            show_advanced: false,
        }
    }
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        // 主中央面板
        egui::CentralPanel::default().show(ctx, |ui| {
            // 标题
            ui.heading("re_ui 完整示例应用");
            ui.add_space(20.0);
            
            // 文本输入区域
            ui.label("请输入文本:");
            ui.text_edit_singleline(&mut self.text_input);
            
            ui.add_space(15.0);
            
            // 按钮和计数器
            if ui.button(format!("点击计数: {}", self.click_count)).clicked() {
                self.click_count += 1;
                println!("按钮被点击 {} 次!", self.click_count);
            }
            
            ui.add_space(15.0);
            
            // 切换显示高级选项
            ui.checkbox(&mut self.show_advanced, "显示高级选项");
            
            if self.show_advanced {
                ui.add_space(10.0);
                ui.collapsing("高级设置", |ui| {
                    ui.label("这里是高级设置选项");
                    ui.slider(0..=100, &mut 50, "滑块值");
                });
            }
            
            ui.add_space(20.0);
            
            // 分隔线
            ui.separator();
            
            // 底部信息
            ui.label("这是一个使用 re_ui 主题的完整示例应用");
            ui.label(format!("当前输入: {}", self.text_input));
        });
        
        // 侧边栏示例
        egui::SidePanel::left("side_panel").show(ctx, |ui| {
            ui.heading("导航");
            ui.separator();
            
            if ui.button("主页").clicked() {
                println("导航到主页");
            }
            if ui.button("设置").clicked() {
                println("导航到设置");
            }
            if ui.button("关于").clicked() {
                println("导航到关于");
            }
        });
        
        // 顶部菜单栏
        egui::TopBottomPanel::top("menu_bar").show(ctx, |ui| {
            egui::menu::bar(ui, |ui| {
                ui.menu_button("文件", |ui| {
                    if ui.button("新建").clicked() {
                        println("新建文件");
                    }
                    if ui.button("打开").clicked() {
                        println("打开文件");
                    }
                    if ui.button("保存").clicked() {
                        println("保存文件");
                    }
                });
                
                ui.menu_button("编辑", |ui| {
                    if ui.button("撤销").clicked() {
                        println("撤销操作");
                    }
                    if ui.button("重做").clicked() {
                        println("重做操作");
                    }
                });
            });
        });
    }
}

这个完整示例展示了 re_ui 的更多功能,包括:

  • 文本输入处理
  • 按钮点击计数
  • 复选框和折叠面板
  • 侧边栏导航
  • 顶部菜单栏
  • 响应式布局

要运行此示例,请确保在 Cargo.toml 中添加正确的依赖版本。


1 回复

re_ui:轻量级、模块化与跨平台的Rust UI组件库

概述

re_ui是一个专为Rust语言设计的现代化UI组件库,专注于提供轻量级、模块化和跨平台的用户界面开发解决方案。该库采用简洁的设计理念,支持快速构建高性能的桌面应用程序界面。

核心特性

  • 轻量级架构:最小化依赖,减少应用体积
  • 模块化设计:可按需引入组件,灵活组合
  • 跨平台支持:兼容Windows、macOS和Linux
  • 响应式布局:自适应不同屏幕尺寸
  • 主题定制:支持明暗主题切换

安装方法

在Cargo.toml中添加依赖:

[dependencies]
re_ui = "0.5.0"

基础使用示例

use re_ui::prelude::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化应用
    let app = Application::new()?;
    
    // 创建主窗口
    let window = Window::builder()
        .title("re_ui示例")
        .size(800, 600)
        .build();
    
    // 创建垂直布局容器
    let layout = VBox::new()
        .spacing(10)
        .padding(20);
    
    // 添加按钮组件
    let button = Button::new("点击我")
        .on_click(|| {
            println!("按钮被点击!");
        });
    
    layout.add_child(button);
    
    // 添加文本输入框
    let text_input = TextInput::new()
        .placeholder("请输入文本...");
    
    layout.add_child(text_input);
    
    // 设置窗口内容
    window.set_content(layout);
    
    // 运行应用
    app.run()?;
    
    Ok(())
}

主题定制示例

use re_ui::prelude::*;

fn customize_theme() {
    let mut theme = Theme::default();
    
    // 自定义颜色方案
    theme.colors.primary = Color::from_rgb(0.2, 0.6, 0.8);
    theme.colors.background = Color::from_rgb(0.95, 0.95, 0.95);
    
    // 自定义字体
    theme.typography.heading = Font::new("Roboto", 24.0);
    theme.typography.body = Font::new("Roboto", 16.0);
    
    // 应用主题
    Theme::set_global(theme);
}

响应式布局示例

use re_ui::prelude::*;

fn responsive_layout() -> impl Widget {
    // 使用响应式容器
    ResponsiveContainer::new()
        .breakpoint(768, |_| {
            // 小屏幕布局
            VBox::new()
                .add_child(Label::new("移动端布局"))
                .add_child(Button::new("移动端按钮"))
        })
        .default(|| {
            // 默认桌面布局
            HBox::new()
                .add_child(Label::new("桌面端布局"))
                .add_child(Button::new("桌面端按钮"))
        })
}

模块化组件使用

use re_ui::components::{Card, Avatar, Badge};

fn user_profile_card() -> impl Widget {
    Card::new()
        .add_header(
            HBox::new()
                .add_child(Avatar::new("用户头像"))
                .add_child(Label::new("用户名").bold())
                .add_child(Badge::new("在线").success())
        )
        .add_content(Label::new("用户简介文本..."))
        .add_footer(
            HBox::new()
                .add_child(Button::new("关注"))
                .add_child(Button::new("消息"))
        )
}

完整示例demo

use re_ui::prelude::*;
use re_ui::components::{Card, Avatar, Badge};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化应用
    let app = Application::new()?;
    
    // 自定义主题
    let mut theme = Theme::default();
    theme.colors.primary = Color::from_rgb(0.2, 0.6, 0.8);
    theme.colors.background = Color::from_rgb(0.95, 0.95, 0.95);
    Theme::set_global(theme);
    
    // 创建主窗口
    let window = Window::builder()
        .title("re_ui完整示例")
        .size(1000, 700)
        .build();
    
    // 创建主布局容器
    let main_layout = VBox::new()
        .spacing(20)
        .padding(30);
    
    // 添加标题
    let title = Label::new("用户管理系统")
        .font_size(28)
        .bold();
    
    main_layout.add_child(title);
    
    // 添加用户卡片
    let user_card = create_user_card();
    main_layout.add_child(user_card);
    
    // 添加功能按钮区域
    let button_row = HBox::new()
        .spacing(15)
        .add_child(Button::new("添加用户").primary())
        .add_child(Button::new("编辑用户"))
        .add_child(Button::new("删除用户").danger());
    
    main_layout.add_child(button_row);
    
    // 添加搜索区域
    let search_section = HBox::new()
        .spacing(10)
        .add_child(TextInput::new().placeholder("搜索用户..."))
        .add_child(Button::new("搜索"));
    
    main_layout.add_child(search_section);
    
    // 设置窗口内容
    window.set_content(main_layout);
    
    // 运行应用
    app.run()?;
    
    Ok(())
}

// 创建用户卡片组件
fn create_user_card() -> impl Widget {
    Card::new()
        .padding(20)
        .add_header(
            HBox::new()
                .spacing(15)
                .add_child(Avatar::new("用户头像"))
                .add_child(
                    VBox::new()
                        .add_child(Label::new("张三").bold().font_size(18))
                        .add_child(Label::new("高级用户").secondary())
                )
                .add_child(Badge::new("在线").success())
        )
        .add_content(
            VBox::new()
                .spacing(10)
                .add_child(Label::new("邮箱: zhangsan@example.com"))
                .add_child(Label::new("电话: 138-8888-8888"))
                .add_child(Label::new("部门: 技术研发部"))
        )
        .add_footer(
            HBox::new()
                .spacing(10)
                .add_child(Button::new("查看详情"))
                .add_child(Button::new("发送消息").primary())
                .add_child(Button::new("编辑资料"))
        )
}

// 响应式布局示例函数
fn create_responsive_content() -> impl Widget {
    ResponsiveContainer::new()
        .breakpoint(768, |_| {
            // 移动端布局
            VBox::new()
                .spacing(15)
                .add_child(Label::new("移动端界面"))
                .add_child(Button::new("菜单"))
                .add_child(TextInput::new().placeholder("搜索..."))
        })
        .default(|| {
            // 桌面端布局
            HBox::new()
                .spacing(20)
                .add_child(Label::new("桌面端界面").expanded())
                .add_child(Button::new("文件"))
                .add_child(Button::new("编辑"))
                .add_child(Button::new("视图"))
                .add_child(TextInput::new().placeholder("全局搜索..."))
        })
}

最佳实践建议

  1. 按需导入:只导入需要的模块以减少编译时间
  2. 状态管理:结合Rust的所有权系统设计组件状态
  3. 错误处理:妥善处理UI操作可能产生的错误
  4. 性能优化:对大型列表使用虚拟滚动
  5. 测试策略:编写组件单元测试和集成测试

re_ui提供了完整的文档和示例。

回到顶部