【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…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
