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

说在前面

  • 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")
    

    运行后出现报错 (错误提示还挺全) 在这里插入图片描述

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

  • 当然我们也可以调用bottom()方法,对应枚举TopBottomSide::Bottom
    在这里插入图片描述

  • 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(...
    

    在这里插入图片描述

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.
    
    在这里插入图片描述
    放到bottom会盖住菜单(File):
    在这里插入图片描述

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();}});
    });
    
    效果如图
    在这里插入图片描述
  • 如果menu_button直接放在panel中会怎样呢?
    在这里插入图片描述
    其实也是可以的,只是效果不是很好,对比一下(上图是放在panel中,下图是放在bar中的效果):
    在这里插入图片描述

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 interactfill: 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();
    }
    
    在这里插入图片描述
    在这里插入图片描述
  • 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/80718.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树搜索

✅<1>主页&#xff1a;我的代码爱吃辣&#x1f4c3;<2>知识讲解&#xff1a;数据结构——二叉搜索树☂️<3>开发环境 &#xff1a;Visual Studio 2022&#x1f4ac;<4>前言&#xff1a;在之前的我们已经学过了普通二叉树&#xff0c;了解了基本的二叉树…

【Windows 常用工具系列 10 -- linux ssh登录脚本输入密码】

文章目录 脚本输入SSH登录密码scp 脚本免密传输 脚本输入SSH登录密码 sshpass 是一个用于运行时非交互式ssh密码提供的工具&#xff0c;它允许你直接在命令行中为ssh命令提供密码。这就意味着你可以在脚本中使用ssh命令&#xff0c;而不需要用户交互地输入密码。 一般来说&am…

SpringCloud入门实战(十四)Sentinel微服务流量防卫兵简介

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 &#xff0c;关注我&#xff0c;不迷路 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术…

C语言暑假刷题冲刺篇——day4

目录 一、选择题 二、编程题 &#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C语言每日一练 ✨其他专栏&#xff1a;代码小游戏C语言初阶&#x1f91d;希望作者的文章能对你…

Java“牵手”快手商品列表数据,关键词搜索快手商品数据接口,快手API申请指南

快手商城是一个网上批发购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取快手商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问快手商城的网页来获取商品详情信息。以下是两种常用方法的介绍…

Objectarx 2021使用vs2019生成报错 /RTCc rejects conformant code

error C2338: /RTCc rejects conformant code错误解决 使用VS2019/VS2022生成项目报错 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C1189 #error: /RTCc rejects conformant code, so it is not supported by the C Standard Library. Either remove this compiler opti…

AI狂飙,云端IDE如何书写未来?TVP吐槽大会邀您来论道

随着云原生的发展&#xff0c;数字化转型的深入&#xff0c;云端开发场景越发丰富&#xff0c;今年&#xff0c;云端 IDE 逐渐成为聚光灯下的一大焦点&#xff0c;CNCF 在 2023 年云原生预测中提出 “云原生 IDE 成为常态”。云端 IDE 创造了一个端到端的开发环境&#xff0c;并…

意外发现Cortex-M内核带的64bit时间戳,比32bit的DWT时钟周期计数器更方便,再也不用担心溢出问题了

视频&#xff1a; https://www.bilibili.com/video/BV1Bw411D7F5 意外发现Cortex-M内核带的64bit时间戳&#xff0c;比32bit的DWT时钟周期计数器更方便&#xff0c;再也不用担心溢出问题了 介绍&#xff1a; 看参数手册的Debug章节&#xff0c;System ROM Table里面带Timestam…

解锁ChatGLM-6B的潜力:优化大语言模型训练,突破任务困难与答案解析难题

解锁ChatGLM-6B的潜力&#xff1a;优化大语言模型训练&#xff0c;突破任务困难与答案解析难题 LLM&#xff08;Large Language Model&#xff09;通常拥有大量的先验知识&#xff0c;使得其在许多自然语言处理任务上都有着不错的性能。 但&#xff0c;想要直接利用 LLM 完成…

Vue Element upload组件和Iview upload 组件上传文件

今天要分享的是使用这俩个UI组件库的upload组件分别实现调用组件本身的上传方法实现和后台交互。接下来就是开车的时间&#xff0c;请坐稳扶好~ 一、element upload组件传送门 1、html文件 <el-upload ref"uploadRef" :action"uploadUrl" :data"…

一篇文章带你学好--->Git(超详细)

Git的详解与使用&#xff0c;一篇文章带你学习好git, ,Git是当前比较流行的版本控制工具 &#xff0c;它具有分布式的功能 &#xff0c;有助于我们在团队开发中提高开发效率 注意&#xff1a;敲黑板&#xff01;&#xff01;&#xff01; 带领你去使用git 配有图文解释 超详细 …

使用 Sahi 实现 Web 自动化测试

Sahi 是 Tyto Software 旗下的一个基于业务的开源 Web 应用自动化测试工具。Sahi 运行为一个代理服务器&#xff0c;并通过注入 JavaScript 来访问 Web 页面中的元素。Sahi 支持 HTTPS 并且独立于 Web 站点&#xff0c;简单小巧却功能强大。它相对于 Selenium 等自动化测试工具…