<Rust>egui部件学习:如何在egui窗口中添加按钮button以及标签label部件?

news2024/11/13 9:14:45

前言
本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析,主要讲解egui的源代码、部件属性、如何应用。

环境配置
系统:windows
平台:visual studio code
语言:rust
库:egui、eframe

概述
本文是本专栏的第二篇博文,主要讲述按钮button、标签label部件的使用。

事实上,类似于iced,egui都提供了示例程序,本专栏的博文都是建立在官方示例程序以及源代码的基础上,进行的实例讲解。
即,本专栏的文章并非只是简单的翻译egui的官方示例与文档,而是针对于官方代码进行的实际使用,会在官方的代码上进行修改,包括解决一些问题。

系列博文链接:
1、<Rust>egui部件学习:如何在窗口及部件显示中文字符?

基于第一篇文章,我们将设置自定义字体的函数写到单独的mod里:
在这里插入图片描述
名称可以自己起,如setfont,然后我们在main中调用函数即可。具体函数代码和之前是一样的,就不重复贴了,但是这里稍作了修改,将字体的字节数组作为参数传给函数:

pub fn setup_custom_fonts(ctx: &egui::Context,fontbyte:&'static [u8]) 

并且为了能在其他mod里调用,函数前面添加了pub关键词。

在第一篇中,我们只是介绍了如何显示中文字符,本文我们会说明窗口的显示,以及如何添加按钮、标签部件。

部件属性
窗口显示

先来看窗口的显示,不同于iced库。egui的部件显示和更新都放在了update函数里。而iced的部件显示放在view函数,响应则放在update中。
官方给出的典型的egui代码如下:

use eframe::egui;            

fn main() {
    let native_options = eframe::NativeOptions::default();
     eframe::run_native("My egui App", native_options, Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc)))));
}

 #[derive(Default)]
 struct MyEguiApp {}

 impl MyEguiApp {
     fn new(cc: &eframe::CreationContext<'_>) -> Self {
         // Customize egui here with cc.egui_ctx.set_fonts and cc.egui_ctx.set_visuals.
         // Restore app state using cc.storage (requires the "persistence" feature).
         // Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use
         // for e.g. egui::PaintCallback.
         Self::default()
     }
 }

 impl eframe::App for MyEguiApp {
    fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading("Hello World!");
        });
    }
 }

和iced是有些类似的,我们创建一个结构体,里面是我们要操作的数据,然后我们为其实现eframe的app特性,窗口建立后,结构体数据就可以通过app的update来更新了。
不同于iced,iced中application是包含了new函数的,但是egui的app中,并没有直接添加new,而是需要单独实现:

impl MyApp{
    fn new(cc: &eframe::CreationContext<'_>) -> Self { 
        setfont::setup_custom_fonts(&cc.egui_ctx,MY_FONTS_BYTES);
        Self {
            show_confirmation_dialog:false,
            allowed_to_close:false,
        }
    }
}

我们设置自定义字体,就是在new函数中初始化的。

按钮部件button

窗口可以显示了,但是运行后只是一个空的窗体,我们需要在其中添加按钮等部件,以实现和窗口的交互。
egui中,部件的添加,都是在show函数里:

 egui::CentralPanel::default().show(ctx, |ui| {  
            ui.heading("尝试关闭窗口");
            ui.button("按钮1")
            
        });

如上,show有两个参数,ctx可以设置UI的格式,而add_contents用于添加其他部件:

ui.button("按钮1") 

这种方式是快捷的调用,它返回的是一个Response,即交互数据,我们可以使用Response来进行逻辑处理。比如,按钮点击响应,可以这样设置:

 let btn_res=ui.button("按钮1");                  
 if btn_res.clicked(){
        println!("按钮1点击")
 }else {
                
}

根据egui的介绍,egui是即时模式,作者在github解释了这个问题:
在这里插入图片描述
在这里插入图片描述
所以,根据作者的说明,egui是很适合集成到游戏开发中的,如果你要了解更多,可以参考作者给出的说明:
https://docs.rs/egui/latest/egui/#understanding-immediate-mode

总的来说,egui并不需要存储部件以供使用,而是即时刷新,所以,egui的缺点是布局不是很方便,因为是即时刷新,所以需要提前知道布局。而且,有些场景下,可能还会有很大的问题,这是一个需要注意的点。

好了,我们现在回到本文的内容上,我们在update中添加了按钮后,我们来运行看一下:
在这里插入图片描述
当我们点击按钮后,会在控制台打印文本:
在这里插入图片描述

标签部件label

现在我们在窗口添加标签,点击按钮,将文本显示在标签上。

 let btn_res=ui.button("按钮1"); 
            if btn_res.clicked(){
                //println!("按钮1点击")
                self.lbltext="按钮1点击".to_string();
            }else {
                
            }
            ui.label(format!("{}",self.lbltext))

如上,我们添加了label,其文本内容是一个格式化的参数:

format!("{}",self.lbltext)

这样设置是为了文本可以动态变化,其中self.lbltext是我们在结构体中创建的元素:

#[derive(Default)]
struct MyApp {
    show_confirmation_dialog: bool,   
    allowed_to_close: bool,
    lbltext:String,
}

这样,运行后,我们点击按钮,就可以在标签上显示内容:
在这里插入图片描述
在这里插入图片描述
当然,我们也可以是文本框输入部件,来动态输入文本,来查看标签内容变化,不够,文本输入我们将在下一个章节里介绍,本文就不在赘述了。

完整代码

main.rs

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release      
#![allow(rustdoc::missing_crate_level_docs)] // it's an example 

use eframe::egui; 

mod setfont; 

const MY_FONTS_BYTES:&[u8]=include_bytes!("../font/simsun.ttf"); 

fn main() -> eframe::Result { 
    env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). 
    let options = eframe::NativeOptions { 
        viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]), 
        ..Default::default() 
    };
    eframe::run_native( 
        "egui测试窗口",
        options, 
        //Box::new(|_cc| Ok(Box::<MyApp>::default())), 
        Box::new(|cc| Ok(Box::new(MyApp::new(cc)))), 
    )
}



#[derive(Default)]
struct MyApp {
    show_confirmation_dialog: bool, 
    allowed_to_close: bool, 
    lbltext:String, 
}

impl MyApp{
    fn new(cc: &eframe::CreationContext<'_>) -> Self { 
        setfont::setup_custom_fonts(&cc.egui_ctx,MY_FONTS_BYTES); 
        Self { 
            show_confirmation_dialog:false, 
            allowed_to_close:false, 
            lbltext:"no text".to_string(), 
        }
    }
}

impl eframe::App for MyApp { 
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { 
        egui::CentralPanel::default().show(ctx, |ui| { 
            ui.heading("尝试关闭窗口");
            let btn_res=ui.button("按钮1"); 
            if btn_res.clicked(){ 
                //println!("按钮1点击")
                self.lbltext="按钮1点击".to_string();
            }else { 
                
            }
            ui.text_edit_singleline(&mut self.lbltext); 
            ui.label(format!("{}",self.lbltext))
            
        });

        // if ctx.input(|i| i.viewport().close_requested()) { 
        //     if self.allowed_to_close { 
        //         // do nothing - we will close 
        //     } else { 
        //         ctx.send_viewport_cmd(egui::ViewportCommand::CancelClose); 
        //         self.show_confirmation_dialog = true; 
        //     }
        // }

        if self.show_confirmation_dialog { 
            egui::Window::new("你想要关闭吗?")
                .collapsible(false)
                .resizable(false)
                .show(ctx, |ui| { 
                    ui.horizontal(|ui| { 
                        if ui.button("否").clicked() { 
                            self.show_confirmation_dialog = false; 
                            self.allowed_to_close = false; 
                        }

                        if ui.button("是").clicked() { 
                            self.show_confirmation_dialog = false; 
                            self.allowed_to_close = true; 
                            ui.ctx().send_viewport_cmd(egui::ViewportCommand::Close); 
                        }
                    });
                });
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

15. 【C++】详解搜索二叉树 | KV模型

目录 1.定义 初始化 插入 查找 删除 完整代码 2.运用 K 模型和 KV 模型详解 K 模型 KV 模型 代码解释 为了更好地理解 map 和 set 的特性&#xff0c;和后面讲解查找效率极高的平衡搜索二叉树&#xff0c;和红黑树去实现模拟&#xff0c;所以决定在这里对搜索二叉树…

基于asp.net小区物业信息管理系统设计与实现

博主介绍&#xff1a;专注于Java .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的可以…

【机器学习】使用Python的dlib库实现人脸识别技术

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、传统人脸识别技术1. 基于几何特征的方法2. 基于模板匹配的方法3. 基于统计学习的方法 三、深度学习在脸识别中的应用1. 卷积神经网络&#xff08;CNN&#xff09;2. FaceNet和ArcFace 四、使用Python和dlib库实…

辅助类BigDecima/BigInteger

** 大数据的运算** 编号1方法解释1add2subtract-3multiply*4divide/

p19 C语言操作符详解

算术操作符 1.除了%操作符之外&#xff0c;其他的几个操作符可以作用于整数和浮点数。 2.对于/操作符如果两个操作数都为整数&#xff0c;执行整数除法。而只要有浮点数值型的就是浮点除法。 3.%操作符的两个操作数必须为 整数。返回的是整除之后的余数。 #include<std…

通信流程:https【SSL/TLS】,git仓库【https/SSH】,蓝牙【面对面快传/AirDrop】

目录 HTTPS HTTP&#xff08;80端口&#xff09; SSL/TLS协议&#xff08;传输层&#xff0c;443端口&#xff09; 密文传输&#xff1a;SSL的后续版本TLS TLS1.2握手 1.摘要算法(散列函数 Hash Function)&#xff1a;验证信息的完整性&#xff0c;不可逆 第三方认证 引…

GO:Socket编程

目录 一、TCP/IP协议族和四层模型概述 1.1 互联网协议族&#xff08;TCP/IP&#xff09; 1.2 TCP/IP四层模型 1. 网络访问层&#xff08;Network Access Layer&#xff09; 2. 网络层&#xff08;Internet Layer&#xff09; 3. 传输层&#xff08;Transport Layer&#…

kotlin compose 实现应用内多语言切换(不重新打开App)

1. 示例图 2.具体实现 如何实现上述示例,且不需要重新打开App ①自定义 MainApplication 实现 Application ,定义两个变量: class MainApplication : Application() { object GlobalDpData { var language: String = "" var defaultLanguage: Strin…

你不是拖延,是没找对感觉!

在这个快节奏的时代&#xff0c;学习效率成为了我们每个人都渴望提升的关键能力。如何通过训练潜意识、深化知识印象、调整学习模式、找到适合自己的学习方法&#xff0c;以及利用倒计时硬逼法来提高执行力&#xff1f; 1. 训练潜意识&#xff1a;形成习惯 习惯的力量是巨大的…

使用python的pillow库生成图像验证码

一、pillow库 Pillow库&#xff1a;是一个功能强大的Python图像处理库&#xff0c;它提供了丰富的图像处理功能&#xff0c;使得用户能够方便地使用Python对图像进行各种操作。 二、图像验证码的分析 首先需要一个图像&#xff0c;图像上需要绘制验证码&#xff0c;还需要任意多…

博客最细 STM32CubeProgrammer 软件使用教程 二(学不会举报我)

前言&#xff1a;编写不易&#xff0c;仅供学习&#xff0c;参考&#xff0c;请勿转载 前言&#xff1a;本篇教程是 STM32CubeProgrammer 软件使用教程二&#xff0c;通过本篇你可以学习到&#xff0c;使用STM32CubeProgrammer读取 flash RAM&#xff0c;开启读写保护&#x…

科普文:TaobaoVM信息收集

网上关于TaobaoVM的信息很少&#xff0c;只有一个简介&#xff0c;就没有其他信息。毕竟这是别人企业自己的jvm&#xff0c;不可能公开。 Taobao VM 由AliJVM团队发布。阿里&#xff0c;国内使用Java最强大的公司&#xff0c;覆盖云计算、金融、物流、电商等众多领域&#xf…

Python和C++行人轨迹预推算和空间机器人多传感融合双图算法模型

&#x1f3af;要点 &#x1f3af;双图神经网络模型&#xff1a;最大后验推理和线性纠错码解码器 | &#x1f3af;重复结构和过约束问题超图推理模型 | &#x1f3af;无向图模型变量概率计算、和积消息传播图结构计算、隐马尔可夫模型图结构计算、矩阵图结构计算、图结构学习 |…

数据库MySQL学习第一天|了解数据库、数据类型、存储引擎、sql语言

文章目录 了解数据库什么是数据库数据库分类MySQL概念 数据类型整数类型小数类型日期类型文本,二进制类型 存储引擎种类引擎选择 sql主键和外键主键设计原则选取策略 外键索引 表与表的关联在语法上关联关系sql约束sql注入聚合函数常见查询关键字 了解数据库 什么是数据库 概…

网络安全协议系列

目录 一、安全协议的引入 1.TCP/IP协议族中普通协议的安全缺陷 1.信息泄露 2.信息篡改 3.身份伪装 4.行为否认 2.网络安全需求 二、网络安全协议的定义 三、构建网络安全协议所需的组件 1.加密与解密 2.消息摘要 3.消息验证码 4.数字签名 5.密钥管理 1.建立共享…

关于C#多个文本框输入的问题

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

堆排序基本思想以及代码实现

1、基本思想 堆排序是利用堆这种数据结构而设计的一种排序算法&#xff0c;堆排序是一种选择排序&#xff0c;它的最坏&#xff0c;最好&#xff0c;平均时间复杂度均为O(n*logn)&#xff0c;它也是不稳定排序。 堆是具有以下性质的完全二叉树&#xff1a;每个结点的值都大于或…

Vue3路由如何携带 # 路由模式选择

vue3中创建路由的时候&#xff0c;有两种可选模型 hash模式、HTML5模式、服务端渲染模式 createWebHashHistory&#xff08;hash模式&#xff09; const router createRouter({// hash模式&#xff0c;带 # 号history: createWebHashHistory(), //函数可携带参数&#xff0c;…

C++11 容器emplace方法刨析

如果是直接插入对象 push_back()和emplace_back()没有区别但如果直接传入构造函数所需参数&#xff0c;emplace_back()会直接在容器底层构造对象&#xff0c;省去了调用拷贝构造或者移动构造的过程 class Test { public:Test(int a){cout<<"Test(int)"<<…

使用Web控制端和轻量级客户端构建的开放Web应用防火墙(OpenWAF)

目录 1. 简介2. 项目结构3. Web控制端3.1. 功能概述3.2. 审计&#xff08;攻击&#xff09;日志查看3.3. 多个WAF的集中监控和操作3.4. 使用socket进行封装3.5. 日志的高效存储和检索&#xff08;Redis&#xff09; 4. 轻量级客户端4.1. 功能概述4.2. 对Web程序的防护4.3. 网络…