【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button

这篇具有很好参考价值的文章主要介绍了【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说在前面

  • rust新手,egui没啥找到啥教程,这里自己记录下学习过程
  • 环境:windows11 22H2
  • rust版本:rustc 1.71.1
  • egui版本:0.22.0
  • eframe版本:0.22.0
  • 上一篇:这里

update

  • update实际上还是eframe::App的特征,并非egui的内容。其官方注解如下:
    fn update(&mut self, ctx: &Context, frame: &mut Frame)
    Called each time the UI needs repainting, 
    which may be many times per second.
    
    update函数会在需要重绘ui(或者其他)的时候被调用,一秒可能会调用多次
    (稍微看了下源代码,可能是事件驱动调用?)
  • 我们可以在该函数里加个日志看看调用情况:
    [2023-08-20T07:44:02Z ERROR demo_app::app] update
    [2023-08-20T07:44:02Z ERROR demo_app::app] update
    [2023-08-20T07:44:02Z ERROR demo_app::app] update
    [2023-08-20T07:44:02Z ERROR demo_app::app] update
    [2023-08-20T07:44:02Z ERROR demo_app::app] update
    [2023-08-20T07:44:07Z ERROR demo_app::app] update
    [2023-08-20T07:44:07Z ERROR demo_app::app] update
    
    可以看到,当我们不进行任何操作(鼠标、键盘均不输入)时,是没有任何输出的,当按住任意一个按键后,日志开始疯狂输出,这也印证了事件驱动的猜想。
  • 其他内容本文暂未深入

TopBottomPanel

  • 接下来正式开始接触egui的内容,首先是:

    #[cfg(not(target_arch = "wasm32"))] // 非wasm才有
    egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
        // 顶部的panel通常用于菜单栏
        egui::menu::bar(ui, |ui| {
            ui.menu_button("File", |ui| {
                if ui.button("Quit").clicked() {
                    _frame.close();
                }
            });
        });
    });
    
  • 看看这里面是些什么,首先是top(),其实现如下:

    pub fn top(id: impl Into<Id>) -> Self {
        Self::new(TopBottomSide::Top, id)
    }
    // id需要是全局唯一的, e.g. Id::new("my_top_panel").
    

    参数id:需要实现Into<Id>特征,并且需要全局唯一,那我要是不唯一怎么办,比如把下面的SidePanel也改成一样的:

    egui::SidePanel::left("top_panel")
    

    运行后出现报错 (错误提示还挺全) 【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言

  • 在函数实现中,实际上还是调用的new方法,传入位置的枚举TopBottomSide::Top

  • 当然我们也可以调用bottom()方法,对应枚举TopBottomSide::Bottom
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言

  • new方法的实现如下:

    pub fn new(side: TopBottomSide, id: impl Into<Id>) -> Self {
        Self {
            side,
            id: id.into(), // 调用into方法,转为Id类型
            frame: None,
            resizable: false, // 下面是一些控制参数
            show_separator_line: true,
            default_height: None,
            height_range: 20.0..=f32::INFINITY,
        }
    }
    
  • 紧跟top()的是show()方法:

    pub fn show<R>(
        self,
        ctx: &Context,
        add_contents: impl FnOnce(&mut Ui) -> R
    ) -> InnerResponse<R>
    

    参数add_contentsFnOnce闭包,仅执行一次,在我们的应用中,闭包中添加了一个简单的菜单栏:

    // 添加菜单栏
    egui::menu::bar(ui, |ui| {
        ui.menu_button("File", |ui| {
        	if ui.button("Quit").clicked() {
            	_frame.close();
            }
        });
    });
    
  • 注意:上面说的执行一次,是说此次update调用中执行一次

  • 我们继续深入下TopBottomPanel的定义:

    pub struct TopBottomPanel {
        side: TopBottomSide,
        id: Id,
        frame: Option<Frame>,
        resizable: bool,
        show_separator_line: bool,
        default_height: Option<f32>,
        height_range: RangeInclusive<f32>,
    }
    

    其实是可以修改一些样式的,比如高度:

    egui::TopBottomPanel::top("top_panel").min_height(100.0).show(...
    

    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言文章来源地址https://www.toymoban.com/news/detail-668002.html

menu::bar

  • TopBottomPanel中,我们使用bar()函数添加了一个菜单栏,其函数定义如下:
    pub fn bar<R>(
        ui: &mut Ui,
        add_contents: impl FnOnce(&mut Ui) -> R
    ) -> InnerResponse<R>
    
    同样使用FnOnce闭包来添加一些额外的元素
  • 菜单栏组件在TopBottomPanel::top中的展示效果最好,当然也可以放在Window中。
    The menu bar goes well in a TopBottomPanel::top, 
    but can also be placed in a Window. In the latter case you may want to wrap it in Frame.
    
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言
    放到bottom会盖住菜单(File):
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言

menu::menu_button

  • bar()的回调中,我们添加了一个下拉按钮
    pub fn menu_button<R>(
        ui: &mut Ui,
        title: impl Into<WidgetText>,
        add_contents: impl FnOnce(&mut Ui) -> R
    ) -> InnerResponse<Option<R>>
    Construct a top level menu in a menu bar.
    
    似乎menu_button最好包在menu bar
  • 同时也使用了FnOnce闭包添加了一个按钮:
    ui.menu_button("File", |ui| {
    	if ui.button("Quit").clicked() {
            _frame.close();
        }
    });
    
  • 其实我们还可以在menu_button中添加一个子menu_button
    ui.menu_button("File", |ui| {
        if ui.button("Quit").clicked() {
            _frame.close();
        }
        ui.menu_button("QuitMenu", |ui| {
            if ui.button("Quit").clicked() {
                _frame.close();
            }
        });
    });
    
    效果如图
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言
  • 如果menu_button直接放在panel中会怎样呢?
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言
    其实也是可以的,只是效果不是很好,对比一下(上图是放在panel中,下图是放在bar中的效果):
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言

Ui::button

  • 上面我们已经接触到了文本按钮,其定义如下:
    pub fn button(&mut self, text: impl Into<WidgetText>) -> Response
    
  • 实际上是一个简单的封装函数:
    Button::new(text).ui(self)
    
  • 通常的用法是:
    if ui.button("Click me").clicked() {}
    
  • 现在我们进一步看看Button的定义:
    pub struct Button {
        text: WidgetText,
        shortcut_text: WidgetText,
        wrap: Option<bool>,
        /// None means default for interact
        fill: Option<Color32>,
        stroke: Option<Stroke>,
        sense: Sense,
        small: bool,
        frame: Option<bool>,
        min_size: Vec2,
        rounding: Option<Rounding>,
        image: Option<widgets::Image>,
    }
    
  • 是有一些参数可以设置的,那我们怎样添加一个不一样的按钮呢?
    if ui
        .add(egui::Button::new("q")
        	// .fill(Color32::GOLD)
        	.min_size(egui::Vec2 { x: 20.0, y: 100.0 }))
        .clicked()
    {
        _frame.close();
    }
    
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言
    【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button,Rust,rust,命令模式,开发语言
  • ui.button()ui.add()返回的都是Response,它可以让我们知道ui元素是否被点击、拖拽,进而做出对应的处理;例如点击事件:
    pub fn clicked(&self) -> bool {
        self.clicked[PointerButton::Primary as usize]
    }
    
    其大致流程是:鼠标点击事件被eframe捕获,由egui计算与整个ui的交互结果,例如哪些元素被点击到了,点击结果存储到Response.clicked数组中,我们只需访问即可。
    clicked存储了五种点击事件
    pub enum PointerButton {
        /// The primary mouse button is usually the left one.
        /// 通常是鼠标左键
        Primary = 0,
    
        /// The secondary mouse button is usually the right one,
        /// and most often used for context menus or other optional things.
        /// 通常是鼠标右键
        Secondary = 1,
    
        /// The tertiary mouse button is usually the middle mouse button (e.g. clicking the scroll wheel).
        /// 通常是鼠标中键
        Middle = 2,
    
        /// The first extra mouse button on some mice. In web typically corresponds to the Browser back button.
        Extra1 = 3,
    
        /// The second extra mouse button on some mice. In web typically corresponds to the Browser forward button.
        Extra2 = 4,
    }
    

eframe::Frame::close

  • 调用该函数会通知eframe关闭应用,调用后应用不会立即关闭,而是在该帧结束的时候关闭
  • 同时,如果crate::run_native后面还有代码的话,也会继续执行:
    let ret = eframe::run_native(
        "demo app",
        native_options,
        Box::new(|cc| Box::new(demo_app::TemplateApp::new(cc))),
    );
    
    log::error!("end");
    
    ret
    

参考

  • Button
  • menu_button
  • bar
  • TopBottomPanel
  • update

到了这里,关于【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanel&Button的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【rust/egui】(二)看看template的main函数:日志输出以及eframe run_native

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 首先让我们看看 main.rs 中有些什么 在 eframe 中使用的日志库为 log 以及 env_logger ,其日志等级有5个: 我们可以在main函数中添加测试一

    2024年02月13日
    浏览(31)
  • 【rust/egui】(一)从编译运行template开始

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 rust windows安装参考:这里 本文默认读者已安装相关环境(git、vscode等) egui github demo online 关于 immediate mode wikipedia microsoft learn 先 clone 下这个项目(也可

    2024年02月13日
    浏览(27)
  • RUST egui部署到github

    接上文,当用trunk serve编译部署后,工程目录下就会有一个dist目录,这个目录就是用来部署用的。 :) 创建一个github repo,这个repo的名称有固定格式要求,就是你自己的用户名+github.io,比如我的用户名是crazyskady,那么这个repo就叫crazyskady.github.io 部署就简单了,先把自己的

    2024年03月21日
    浏览(38)
  • [Rust GUI]eframe(egui框架)代码示例

    你可以使用egui的其他绑定,例如:egui-miniquad,bevy_egui,egui_sdl2_gl 等。 egui库相当于核心库,需要借助eframe框架写界面。 eframe使用egui_glow渲染,而egui_glow需要opengl2.0+。 1、访问微软官网下载生成工具 2、勾选这个 3、对比勾选细节 4、点击安装 5、安装完成 6、关闭 Visual Studio

    2024年02月08日
    浏览(35)
  • Rust图形界面:从零开始创建eGUi项目

    egui系列:初步 首先,用cargo创建一个新项目,并添加eframe 尽管默认创建的项目只实现了输出Hello world功能,但添加了eframe库,所以下载需要一点时间。 创建成功后,直接把下面的代码写入main.rs文件中,这些代码来自egui的hello_world示例。 然后运行cargo run,结果如下所示 在e

    2024年02月01日
    浏览(47)
  • 【rust/egui】(十)使用painter绘制一些图形—connections

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 在上一节我们使用 painter 绘制了一个可以拖拽的小方块,现在我们来用 painter 将两个小方块连接起来,类似这种: 首先我们需要在我们

    2024年02月09日
    浏览(29)
  • 【Rust日报】2023-02-14 Rust GUI 框架对比: Tauri vs Iced vs egui

    Rust GUI 框架对比: Tauri vs Iced vs egui Tauri:使用系统的 webview 来渲染 HTML/JS 的前端。你可以选择任何前端框架。后台是用Rust编写的,可以通过内置的方法与前台通信。 Iced: 受 Elm 启发的(响应式)GUI库。在桌面上使用 wgpu 进行渲染;实验性的web后端创建DOM进行渲染。所有代码

    2024年02月02日
    浏览(27)
  • 【rust/egui】(八)使用panels给你的应用划分功能区块

    rust新手,egui没啥找到啥教程,这里自己记录下学习过程 环境:windows11 22H2 rust版本:rustc 1.71.1 egui版本:0.22.0 eframe版本:0.22.0 上一篇:这里 panel 是ui上的一块区域,比如我们打开CSDN的markdown编辑器,它大致上可以划分成四(五)块 (当然实际实现上这四块区域可能不是并列的

    2024年02月09日
    浏览(29)
  • k8s helm ingress-nginx Error: template: ingress-nginx/templates/controller-role “update-status“

    k8s,使用helm包管理器安装ingress-nginx时,安装文件出错 helm 版本:Version:“v3.2.3” k8s 版本:Kubernetes v1.23.6 ingress-nginx chart version:4.9.0 app version:1.9.5 前面都按网上的教程做,没有什么大问题 最后一步执行安装命令 命令执行失败,报错 问题可能出现在对.Values.controller.extraArg

    2024年03月20日
    浏览(106)
  • 【rust/bevy】从game template开始

    操作系统:win11 rust版本:rustc 1.77.0-nightly bevy版本:0.12 rust安装 这里 windows 下建议使用 msvc 版本 bevy 安装 这里 clone代码 运行 结果 template中的例子是2d的,我们稍微修改下 首先增加一个 CameraController ,代码在 bevy 的例程中也可以找到 再添加一个 SceneSetup ,用于初始化场景和相

    2024年01月18日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包