【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);}
    
    日志输出为:
    [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
    
    可以看到,在输入字符的那一次update中,变量值在函数开始时并没有发生变化,也就是说刚刚的猜想是错的🤡
  • 那是怎么回事呢?
    在这里插入图片描述
  • 让我们回过头来看看events()的引用,居然是在show()函数中被调用的,而show()是在update中调用的
  • 所以实际的过程应该是:
    • 应用启动,update会首次调用一次,这个时候,我们的变量label通过层层转移,最终显示到文本框中。
    • 这个时候输入字符,eframe监听到事件,将事件通知egui进行分发并调用update函数
    • label变量再次进行绑定
    • 之后,在TextEdit对应的show()方法中,检测到对应的事件,进而修改对应的变量值
    • 更新ui

参考

  • Rust: the weird but safe string
  • TextEdit

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

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

相关文章

SQL Server 配置管理器不见了

SQL Server 配置管理器不见了 错误重现&#xff1a; 之前安装好的SQL Server 2012打开都没有问题&#xff0c;好多天没有打开了&#xff0c;今天打开我的SQL Server 2012 连接时出现错误&#xff1a; 在与SQL Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或…

如何打开sql server配置管理器

1. 在开始菜单中找 2.如果开始菜单中找不到 按 win键R键 打开后在里面输入 SQLServerManager10.msc 这里的 SQLServerManager10.msc 对应的是SQL Sever 2008 SQL Sever 2019版本的对应的是 SQLServerManager15.msc 具体你sql server的版本对应的哪个&#xff0c;可以去C:\…

SQL 配置管理器找不到了

想用数据库建立远程连接&#xff0c;于是想把数据库改成IP地址连接&#xff0c;突然发现配置管理器不见了&#xff01;&#xff01;&#xff01;&#xff01;&#xff1f;&#xff1f;&#xff1f;百度了一下&#xff0c;有人说可以用win R打开后&#xff0c;输入 SQLServerMa…

SQLServer找不到配置管理器,如何打开配置管理器

总有些sqlserver安装完毕之后找不到配置管理器&#xff0c;想看个端口号或者看个服务的用户名&#xff0c;都很气。下面来介绍一下通过windows命令来打开SQLSERVER配置管理器。 首先&#xff1a;windows键R键 各个sqlserver版本在textbox中输入对应的命令如下&#xff1a; SQ…

空号检测API 接入的Java 和 Python 代码总结

空号检测api 是一种基于手机号码查询的技术工具&#xff0c;可以帮助企业准确识别无效手机号&#xff0c;包括空号、停机、库无等状态。通过使用空号检测API&#xff0c;企业能够过滤掉无效的手机号&#xff0c;确保将有限的资源和精力用于有效的目标客户群体&#xff0c;从而提…

【git进阶使用】 告别只会git clone 学会版本控制 ignore筛选 merge冲突等进阶操作

git使用大全 基本介绍git 快速上手一 环境安装&#xff08;默认已安装&#xff09;二 远程仓库克隆到本地1 进入rep文件夹目录2 复制远程仓库地址3 git clone克隆仓库内容到本地4 修改后版本控制4.1 修改文件4.2 git status查看版本库文件状态4.3 git add将文件加入版本库暂存区…

圣诞桌面装饰软件Xmas snow for Mac

Xmas snow for Mac是专为Mac用户所设计的圣诞桌面装饰软件&#xff0c;Xmas snow Mac版在您的桌面用下雪的方式来告诉你圣诞新年倒计时。您可以使用Xmas snow Mac破解版在您的桌面上添加圣诞树、圣诞花环、雪花、倒计时&#xff0c;您还可以每小时聆听圣诞节的曲调哦&#xff0…

c语言 桌面下雪程序,用C++写的在桌面上飘雪的特效程序

#include〈windows.h〉 #include〈time.h〉 #include〈stdlib.h〉 #include〈iostream.h〉 const int SnowNumber=500; //雪点数量 struct SnowNode {POINT postion; //雪点位置 int iColor; //先前的颜色 int iSpeed; //下落速度 int iMove; //下落距离 int iStick; //粘贴度 …

Linux/Unix桌面趣事:让桌面下雪

在这个节日里感到孤独么?试一下 Xsnow 吧&#xff01;它是一个可以在 Unix/Linux 桌面下下雪的应用。圣诞老人和他的驯鹿会在屏幕中奔跑&#xff0c;伴随着雪片让你感受到节日的感觉。 我第一次安装它还是在 13、4 年前。它最初是在 1984 年 Macintosh 系统中创造的。你可以用…

一个让桌面下雪的小程序(并非屏幕保护)

以前见到过一个有趣的小程序&#xff0c;叫snow,可以在桌面上下雪&#xff0c;学还可以在窗体边缘、图像边缘堆积&#xff0c;关键是并非屏幕保护&#xff0c;可以边下雪便运行其它程序。 我就用VB模仿了一个。先贴上效果图&#xff1a; 源代码 Private Declare Function GetDC…

桌面下雪软件测试工程师,Snow Flakes屏幕下雪动态屏保 模拟真实降雪情景的屏保程序...

《Snow Flakes屏幕下雪动态屏保》是一个完美模拟真实降雪情景的屏幕保护程序&#xff0c;可以让你的电脑在没有动作时下起片片雪花&#xff0c;也会随着时间而在工作列上堆积起冰来&#xff0c;相当真实。 Snow Flakes屏幕下雪屏保支持在设置视窗中可以依个人喜欢自行设置风势的…

JavaSE实现桌面屏幕下雪功能

效果图&#xff1a; 使用的是Java AWTUtilities API 建议使用JDK1.8 开发工具 IDEA所有代码如下 import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import com.sun.awt.AWTUti…

linux桌面下雪,一个让桌面下雪的ruby 小程序 snow

[Ruby]代码 #!/usr/bin/env ruby # -*- coding: gb18030 -*- # 2011-3 #ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32] #gem 1.6 #gem install win32-api windows-pr windows-api cstruct #比如要使用 GetDC这个API时,搜索包含文字GetDC的文件在这个目录: D:\Ruby18\…

桌面下雪小程序 WIN32

想起以前还没有上大学的时候&#xff0c;过圣诞节&#xff0c;有同学发了一个桌面下雪的小程序。当看到效果的&#xff0c;哇&#xff0c;当时觉得好高端&#xff0c;就想什么时候我也能写出这么一个程序。学了计算机之后&#xff0c;发现这完全可以实现。于是就准备写一个&…

linux命令画圣诞树图片,Linux如何用Xsnow命令让桌面显示下雪特效

Linux系统下其实有很多有趣的命令&#xff0c;利用这些命令可以达到一些特别的效果。比如说Xsnow&#xff0c;可以让桌面下雪。具体应该怎么实现呢&#xff1f;一起来看一下吧。 方法如下&#xff1a; 一、安装 xsnow Debian/Ubuntu/Mint 用户用下面的命令&#xff1a; $ sudo …

桌面下雪程序的编写

一&#xff0e; 综述 考虑到雪花将会很多&#xff0c;并且每个雪花都有自己的行为路径&#xff0c;统一处理比较麻烦&#xff0c;因此自定义一个类CSnowflake&#xff0c;它所呈现的主要接口有两个&#xff1a;下落和“死亡”判断。下落路径由雪花对象自身处理&#xff0c;主框…

桌面下雪软件测试工程师,Xsnow - 在Ubuntu 18.04及更高版本的桌面上下雪

原标题&#xff1a;Xsnow - 在Ubuntu 18.04及更高版本的桌面上下雪 Xsnow&#xff0c;让它在你的桌面上下雪吧&#xff0c;现在正在Ubuntu 18.04或更高版本的Gnome, KDE, FVWM桌面上工作。 Xsnow是一个方便的命令工具&#xff0c;可以将圣诞节带到您的桌面。但是&#xff0c;它…

linux桌面下雪,分享|Linux/Unix 桌面趣事:让桌面下雪

在这个节日里感到孤独么&#xff1f;试一下 Xsnow 吧。它是一个可以在 Unix/Linux 桌面下下雪的应用。圣诞老人和他的驯鹿会在屏幕中奔跑&#xff0c;伴随着雪片让你感受到节日的感觉。 我第一次安装它还是在 13、4 年前。它最初是在 1984 年 Macintosh 系统中创造的。你可以用…

桌面下雪软件测试工程师,Win7系统如何设置桌面下雪屏保?

一个好看的屏保会带给用户一个好的心情&#xff0c;有很多用户包括小编都很喜欢让桌面下雪的屏保&#xff0c;但是有很多用户并不知道要如何设置桌面下雪屏保&#xff0c;下面&#xff0c;小编就来教教大家在Win7系统下设置桌面下雪屏保的方法。 方法/步骤 1、下载解压缩“桌面…

圣诞节到了!!你的桌面下雪了吗?? - Qt趣味开发之让你的桌面下雪

圣诞节到了&#xff0c;写个桌面下雪的程序庆祝一下。过节也是要有仪式感的&#xff01;&#xff01; 显示效果如下&#xff1a; 具有如下功能&#xff1a; 托盘菜单&#xff0c;可以配置、关于作者、退出。可以配置是否下雪、烟花效果&#xff0c;配置雪的浓度和下降的速度…