【rust/egui】(六)看看template的app.rs:TextEdit
说在前面
- rust新手,egui没啥找到啥教程,这里自己记录下学习过程
- 环境:windows11 22H2
- rust版本:rustc 1.71.1
- egui版本:0.22.0
- eframe版本:0.22.0
- 上一篇:这里
TextEdit
-
文本编辑框

-
其定义为:
pub struct TextEdit<'t> {text: &'t mut dyn TextBuffer,hint_text: WidgetText,id: Option<Id>,id_source: Option<Id>,font_selection: FontSelection,text_color: Option<Color32>, // 文本颜色layouter: Option<&'t mut dyn FnMut(&Ui, &str, f32) -> Arc<Galley>>,password: bool, // 是否是密码frame: bool,margin: Vec2, multiline: bool, // 是否支持多行文本interactive: bool, // 是否可编辑desired_width: Option<f32>, // 宽度desired_height_rows: usize, // 文本行数lock_focus: bool,cursor_at_end: bool, min_size: Vec2, // 最小大小align: Align2, // 边距clip_text: bool, // 显示时是否进行裁剪char_limit: usize, // 文字上限 }用起来可能是个简单的东西,但是实际上很是复杂,首先我们来看看它的外观以及用法
-
在
app.rs中,我们是通过以下方式添加的:ui.text_edit_singleline(label);它添加的是一个简单的单行输入框:
pub fn singleline(text: &'t mut dyn TextBuffer) -> Self {Self {desired_height_rows: 1, // 文本行数multiline: false, // 是否多行,否clip_text: true, // 显示时是否裁剪文本,是..Self::multiline(text)} } -
同样,我们可以通过
ui.add()的方式来自定义属性 -
clip_text
ui.add(egui::TextEdit::singleline(label).clip_text(false));效果如下,输入文本后,文本框宽度将随着输入文本扩展

-
interactive
ui.add(egui::TextEdit::singleline(label).clip_text(false).interactive(false));效果如下,文本框将不可编辑,但是同样也不能选中(也就不能复制)

-
我们可以添加一个多行文本输入框看看:
ui.add(egui::TextEdit::multiline(label));效果如下

由于我们使用的是同一个可变引用,所以在任意一个输入框输入文本时,两边会同时改变 -
另外,我们也可以实现不可编辑但是可以选中的效果:
ui.add(egui::TextEdit::multiline(&mut label.as_str()));
- 这里有个地方无法理解,
&mut label.as_str()的类型是&mut &str,这是个啥?对&str的可变引用?&mut &str和&mut str的区别是啥? - 使用
&str倒是能理解,因为text: &'t mut dyn TextBuffer是限定了TextBuffer特征的,而egui只为String和&str实现了该特征,并且一个可变,一个不可变,符合预期。impl TextBuffer for String {fn is_mutable(&self) -> bool {true}// .. }impl<'a> TextBuffer for &'a str {fn is_mutable(&self) -> bool {false}// .. }
- 这里有个地方无法理解,
-
输入框也支持对事件进行响应
let response = ui.add(egui::TextEdit::singleline(&mut my_string)); if response.changed() {// … } if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {// … } -
进阶用法
let output = egui::TextEdit::singleline(label).show(ui); if let Some(text_cursor_range) = output.cursor_range {use egui::TextBuffer as _;let selected_chars = text_cursor_range.as_sorted_char_range();let selected_text = label.char_range(selected_chars);ui.label("Selected text: ");ui.monospace(selected_text); }

变量绑定过程
- 初次接触
update函数以及输入框,对于label变量是怎样和文本输入框的内容绑定在一起还是很感兴趣的,看了一些源码后有一些猜想,这里记录下 - 首先,text是特征对象
TextBuffer的可变引用,而特征TextBuffer则有一些关键的方法,例如insert_text():
通过这些方法可以对变量值进行修改,而后就是调用这些方法的过程是怎样的?impl TextBuffer for String {fn is_mutable(&self) -> bool {true}fn as_str(&self) -> &str {self.as_ref()}fn insert_text(&mut self, text: &str, char_index: usize) -> usize {// Get the byte index from the character indexlet byte_idx = self.byte_index_from_char_index(char_index);// Then insert the stringself.insert_str(byte_idx, text);text.chars().count()}fn delete_char_range(&mut self, char_range: Range<usize>) {assert!(char_range.start <= char_range.end);// Get both byte indiceslet byte_start = self.byte_index_from_char_index(char_range.start);let byte_end = self.byte_index_from_char_index(char_range.end);// Then drain all characters within this rangeself.drain(byte_start..byte_end);}fn clear(&mut self) {self.clear();}fn replace(&mut self, text: &str) {*self = text.to_owned();}fn take(&mut self) -> String {std::mem::take(self)} } - 查找
insert_text()方法的引用,可以找到一个events()函数:/// Check for (keyboard) events to edit the cursor and/or text. /// 监听文本框中光标/文本对应的(键盘)事件 fn events() - 也就是说,在我们使用键盘输入字符时,会触发对应的事件,从而调用到对应的
insert_text()方法,从而改变对应的变量值。 - 但是,这其中又有另外一个问题:在前面的文章中有提到,
update函数也是触发了对应的事件后才会被调用的 ,而我们的变量label是在update函数开始才进行的绑定,那么,这个输入文本 到 对应变量值改变的具体过程(顺序)是怎样的呢? - 首先说猜想 (后面证明该猜想是错误的)
- 应用启动,
update会首次调用一次,这个时候,我们的变量label通过层层转移,最终显示到文本框中。 - 这个时候输入字符,
eframe监听到事件,将事件通知egui进行分发 events()函数触发,修改对应的值egui调用update函数,更新ui
- 应用启动,
- 上面的猜想中,主要的点在于,变量值在
update函数前就被更新了,所以我们可以添加日志进行验证:
日志输出为:fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {let Self { label, value } = self;log::error!("{}", label);// ...log::error!("update end {}", label);}
可以看到,在输入字符的那一次update中,变量值在函数开始时并没有发生变化,也就是说刚刚的猜想是错的🤡[2023-08-27T09:42:45Z ERROR demo_app::app] o0olele [2023-08-27T09:42:45Z ERROR demo_app::app] update end o0olele [2023-08-27T09:42:45Z ERROR demo_app::app] o0olele [2023-08-27T09:42:45Z ERROR demo_app::app] update end o0olele1 - 那是怎么回事呢?

- 让我们回过头来看看
events()的引用,居然是在show()函数中被调用的,而show()是在update中调用的 - 所以实际的过程应该是:
- 应用启动,
update会首次调用一次,这个时候,我们的变量label通过层层转移,最终显示到文本框中。 - 这个时候输入字符,
eframe监听到事件,将事件通知egui进行分发并调用update函数 label变量再次进行绑定- 之后,在
TextEdit对应的show()方法中,检测到对应的事件,进而修改对应的变量值 - 更新ui
- 应用启动,
参考
- Rust: the weird but safe string
- TextEdit
相关文章:
【rust/egui】(六)看看template的app.rs:TextEdit
说在前面 rust新手,egui没啥找到啥教程,这里自己记录下学习过程环境:windows11 22H2rust版本:rustc 1.71.1egui版本:0.22.0eframe版本:0.22.0上一篇:这里 TextEdit 文本编辑框 其定义为&#…...
Redis内存空间预估与内存优化策略:保障数据安全与性能的架构实践
推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 史上最全文档AI绘画stablediffusion资料分享 AI绘画关于SD,MJ,GPT,SDXL百科全书 「java、python面试题」…...
【zookeeper】zookeeper集群安装
环境规划 实际的生产使用中,我们一般推荐搭建奇数多节点的zookeeper集群,如3/5/7。在本次测试中,我使用了centos7 三台服务器搭建,复用了我搭建k8s集群的环境,如下表。 IPhostname192.168.2.140k8s-m1192.168.2.141k…...
CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1)
cuda小白 原文链接 NPP GPU架构近些年也有不少的变化,具体的可以参考别的博主的介绍,都比较详细。还有一些cuda中的专有名词的含义,可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》 常见的NppStatus,…...
计算机视觉-LeNet
目录 LeNet LeNet在手写数字识别上的应用 LeNet在眼疾识别数据集iChallenge-PM上的应用 LeNet LeNet是最早的卷积神经网络之一。1998年,Yann LeCun第一次将LeNet卷积神经网络应用到图像分类上,在手写数字识别任务中取得了巨大成功。LeNet通过连续使用…...
Java 复习笔记 - 面向对象篇
文章目录 一,面向对象概述二,类和对象(一)类和对象的概述(二)定义类的补充注意事项 三,封装四,就近原则和this关键字(一)就近原则(二)…...
行业追踪,2023-08-31
自动复盘 2023-08-31 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...
科技资讯|苹果发布新专利:可在车内定位苹果的智能设备
根据美国商标和专利局近期公示的清单,苹果公司获得了一项名为《车内定位移动设备的系统和方式》专利,概述了在车内狭窄空间内如何定位 iPhone 等移动设备。 Find My 服务现阶段没有使用 UWB 来追踪 iPhone 或者 iPad,而是依赖 GPS 等相关辅…...
浅析Linux SCSI子系统:IO路径
文章目录 概述scsi_cmd:SCSI命令result字段proto_op字段proto_type字段 SCSI命令下发scsi_request_fnscsi_dev_queue_readyscsi_host_queue_ready SCSI命令响应命令请求完成的软中断处理 相关参考 概述 SCSI子系统向上与块层对接,由块层提交的对块设备的…...
linux系统(centos、Ubuntu、银河服务器)备份
制作u盘启动盘 下载usblive系统镜像 Get Kali | Kali Linux 下载u盘启动工具 balenaEtcher - Flash OS images to SD cards & USB drives 点击下载,等待下载完成 双击安装,等待安装完成 双击 启动 选择镜像 选择U盘 开始烧录 等地制作完成 进入…...
堆栈深度超过限制
报错:Cause: com.kingbase8.util.KSQLException: 错误: 堆栈深度超过限制 Hint: 在确定了平台的堆栈深度限制是足够大后,增加配置参数 "max_stack_depth"的值(当前值为2048kB).; 错误: 堆栈深度超过限制 Hint: 在确定了平台的堆栈深度限制是足…...
Linux ptrace系统调用
文章目录 一、ptrace 简介二、ptrace 参数request2.1 PTRACE_TRACEME2.2 PTRACE_PEEKTEXT, PTRACE_PEEKDATA2.3 PTRACE_PEEKUSER2.4 PTRACE_POKETEXT, PTRACE_POKEDATA2.5 PTRACE_POKEUSER2.6 PTRACE_GETREGS, PTRACE_GETFPREGS2.7 PTRACE_GETREGSET2.8 PTRACE_SETREGS, PTRACE…...
CSDN每日一练 |『贝博士发奖金』『Longest Continuous Increasing Subsequence』『最小差值』2023-09-01
CSDN每日一练 |『贝博士发奖金』『Longest Continuous Increasing Subsequence』『最小差值』2023-09-01 一、题目名称:贝博士发奖金二、题目名称:Longest Continuous Increasing Subsequence三、题目名称:最小差值一、题目名称:贝博士发奖金 时间限制:1000ms内存限制:25…...
二维数组创建方式比较
暑假跟着地质队去跑山了,到现在还没结束,今天休息的时候突然刷到了一篇关于C二维数组创建方面的文章,我觉得还是非常不错滴,就将其中提到的新方法和我已经使用过的三种方法进行了比较,发现该方法提高了二维数组的分配、…...
安达发|富士康科技集团利用自动排程APS软件打造智慧工厂
富士康科技集团作为全球领先的3C产品研发制造企业,近年来积极布局智能制造领域,通过引入先进的自动化排程系统(APS),成功打造了智慧工厂,提高了生产质量与效率,降低了生产成本。 富士康集团自2019年下半年提出在观澜厂区建立数字可…...
云计算在大数据分析中的应用与优势
文章目录 云计算在大数据分析中的应用云计算在大数据分析中的优势云计算在大数据分析中的示例未来发展和拓展结论 🎉欢迎来到AIGC人工智能专栏~云计算在大数据分析中的应用与优势 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页:IT陈寒的博客&…...
linux————ELK(日志收集系统集群)
目录 一、为什么要使用ELK 二、ELK作用 二、组件 一、elasticsearch 特点 二、logstash 工作过程 INPUT(输入) FILETER(过滤) OUTPUTS(输出) 三、kibana 三、架构类型 ELK ELKK ELFK ELFKK EFK 四、构建ELk集群…...
Leetcode213 打劫家舍2
思路:既然头尾不能同时取,那就分别算只取头或者只取尾,不考虑特殊情况的话是一个简单的动态规划 class Solution:def rob(self, nums: list[int]) -> int:if len(nums) < 3:return max(nums)max_sum [nums[0], max(nums[1], nums[0])…...
Redis全局命令
"那篝火在银河尽头~" Redis-cli命令启动 现如今,我们已经启动了Redis服务,下⾯将介绍如何使⽤redis-cli连接、操作Redis服务。客户端与服务端交互的方式有两种: ● 第⼀种是交互式⽅式: 后续所有的操作都是通过交互式的⽅式实现,…...
Xml转json
利用fastjson转换,pom文件依赖: <dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version> </dependency> <dependency><groupId>com.alibaba</groupId><artifa…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
