RustGUI学习(iced)之小部件(三):如何使用下拉列表pick_list?

devtools/2024/9/20 7:24:55/ 标签: rust, vscode, iced

前言
本专栏是学习Rust的GUI库iced的合集,将介绍iced涉及的各个小部件分别介绍,最后会汇总为一个总的程序。
iced是RustGUI中比较强大的一个,目前处于发展中(即版本可能会改变),本专栏基于版本0.12.1.

概述
这是本专栏的第三篇,主要讲述下拉列表pick_list部件的使用,会结合实例来说明。
系列博文链接
1、RustGUI学习(iced)之小部件(一):如何使用按钮和文本标签部件
2、RustGUI学习(iced)之小部件(二):如何使用滑动条部件

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

在这里插入图片描述
注:iced是一个受Elm启发而编写,适用于rust语言的跨平台的GUI库。

本篇内容:
1、pick_list

下拉列表部件

pick_list部件在iced中的定义如下:

rust">/// Creates a new [`PickList`].     
///
/// [`PickList`]: crate::PickList
pub fn pick_list<'a, T, L, V, Message, Theme, Renderer>(options: L,selected: Option<V>,on_selected: impl Fn(T) -> Message + 'a,
) -> PickList<'a, T, L, V, Message, Theme, Renderer>
whereT: ToString + PartialEq + Clone + 'a,L: Borrow<[T]> + 'a,V: Borrow<T> + 'a,Message: Clone,Renderer: core::text::Renderer,Theme: pick_list::StyleSheet+ scrollable::StyleSheet+ overlay::menu::StyleSheet+ container::StyleSheet,<Theme as overlay::menu::StyleSheet>::Style:From<<Theme as pick_list::StyleSheet>::Style>,
{PickList::new(options, selected, on_selected)
}

其由PickList来创建:

rust">/// A widget for selecting a single value from a list of options.              
#[allow(missing_debug_implementations)]
pub struct PickList<'a,T,L,V,Message,Theme = crate::Theme,Renderer = crate::Renderer,
> whereT: ToString + PartialEq + Clone,L: Borrow<[T]> + 'a,V: Borrow<T> + 'a,Theme: StyleSheet,Renderer: text::Renderer,
{on_select: Box<dyn Fn(T) -> Message + 'a>,on_open: Option<Message>,on_close: Option<Message>,options: L,placeholder: Option<String>,selected: Option<V>,width: Length,padding: Padding,text_size: Option<Pixels>,text_line_height: text::LineHeight,text_shaping: text::Shaping,font: Option<Renderer::Font>,handle: Handle<Renderer::Font>,style: Theme::Style,
}

我们来看以下pick_list涉及的参数或属性,首先是on_select,从其定义可知这是一个动态指针,在实际使用时,on_select表示当选择下拉列表时,会触发这个事件,其反馈当前选择的项。
然后是on_open和on_close两个属性,分别表示下拉列表在打开和关闭时返回的消息,因为通常来说,下拉列表并不太关注打开和关闭时的状态,所以此参数可以不设置,使用默认即可。
然后是options参数,顾名思义,此参数即是下拉列表部件的下拉选项,从其定义来说,是一个借用类型且具有相同的生命周期(与借用的数组一致)。在实际使用来说,此处应该是一个枚举数组。
placeholder参数比较简单,是一个枚举字符,实际表示下拉列表没有选项时显示的一个提示文字。如下:
在这里插入图片描述
接下来是selected,其定义也是枚举类型,但枚举的参数是借用类型,且具有借用数组一样的生命周期。此参数是实时显示选择的下拉项。需要在update函数里更新,否则下拉列表选择后并不会更新UI。
width、padding、text_size、text_line_height、text_shaping、font这些都是一些基本参数,比较简单,主要设置一些尺寸或者文字。
handle是下拉列表右侧的箭头的属性,默认是箭头,可以修改为其他预设,如:
在这里插入图片描述
修改了箭头的尺寸,显示如上,可以看到和默认的有明显区别。除了箭头外,还可以使用自定义侧icon来替换,只不过需要自行设计。如下:
在这里插入图片描述
使用字符作为handle,但通常来说,下拉列表常见的都是箭头。
再来看最后一个属性,style,和之前的部件一样,style用于设计下拉列表部件的外观,其在iced中的定义如下:

rust">/// A set of rules that dictate the style of a container.  
pub trait StyleSheet {/// The supported style of the [`StyleSheet`].type Style: Default + Clone;/// Produces the active [`Appearance`] of a pick list.fn active(&self, style: &<Self as StyleSheet>::Style) -> Appearance;/// Produces the hovered [`Appearance`] of a pick list.fn hovered(&self, style: &<Self as StyleSheet>::Style) -> Appearance;
}

其中,Appearance定义如下:

rust">/// The appearance of a pick list.       
#[derive(Debug, Clone, Copy)]
pub struct Appearance {/// The text [`Color`] of the pick list.pub text_color: Color,/// The placeholder [`Color`] of the pick list.pub placeholder_color: Color,/// The handle [`Color`] of the pick list.pub handle_color: Color,/// The [`Background`] of the pick list.pub background: Background,/// The [`Border`] of the pick list.pub border: Border,
}

可以看到,pick_list部件的Appearance有五个可设置的属性,其中,text_color是文字颜色,placeholder_color是空闲时的文字颜色,handle_color顾名思义是右侧箭头的颜色,background指背景设置,而border是边框设置。
下面我们设置一下自定义pick_list,首先新建一个pick_list的外观结构体:

rust">struct MyPickListStyle;

然后对结构体实现StyleSheet:

rust">impl pick_list::StyleSheet for MyPickListStyle {    type Style = Theme;//激活时外观fn active(&self, style: &Self::Style) -> pick_list::Appearance {pick_list::Appearance {text_color:Color::from_rgb8(142, 204, 240),placeholder_color:Color::BLACK,handle_color:Color::from_rgb8(18, 27, 155),background:Background::Color(Color::from_rgb8(215, 217, 249)),border:Border{color:Color::BLACK,width:1.0,radius:[3.0;4].into()},}
}fn hovered(&self, style: &Self::Style) -> pick_list::Appearance {pick_list::Appearance {text_color:Color::from_rgb8(76, 87, 240),placeholder_color:Color::BLACK,handle_color:Color::from_rgb8(18, 27, 155),background:Background::Color(Color::from_rgb8(215, 217, 249)),border:Border { color: Color::BLACK, width: 1.0, radius: [3.0;4].into() },}}
}

需要注意的是,pick_list的动态样式有些特别,看一下官方定义:

rust">/// The style of a pick list. 
#[derive(Clone, Default)]
pub enum PickList {/// The default style.#[default]Default,/// A custom style.Custom(Rc<dyn pick_list::StyleSheet<Style = Theme>>,Rc<dyn menu::StyleSheet<Style = Theme>>,),
}

可以看到,其Custom选项有2个参数,除了pick_list样式外,还要求了menu样式,虽然不明白作者为什么这么设置,但如果要实现pick_list的自定义样式,我们必须为其添加第二个参数即menu部件的动态样式,所以我们还需要新建menu样式结构体:

rust">struct MyMenuStyle;

然后设置StyleSheet:

rust">impl menu::StyleSheet for MyMenuStyle {   type Style = Theme;fn appearance(&self, style: &Self::Style) -> menu::Appearance {menu::Appearance{text_color:Color::BLACK,background:Background::Color(Color::from_rgb8(215, 217, 249)),border:Border { color: Color::BLACK, width: 1.0, radius: [3.0;4].into() },selected_text_color:Color::BLACK,selected_background:Background::Color(Color::from_rgb8(180, 184, 248)),}}
}

当自定义样式设置好后,就可以调用了:

rust">let style9=theme::PickList::Custom(Rc::new(MyPickListStyle),Rc::new(MyMenuStyle));  

然后设置pick_list的style属性即可,我们来看一下实际效果:
active:
在这里插入图片描述
hovered:
在这里插入图片描述
可以看到,自定义样式还是非常明显的不同的。

好了,关于属性的设置就说到这,接下来说一下options、selected、on_select这三个选项在实际中如何设置:
先来看一下三个参数的定义:

rust">options: L,

其中,L为:

rust">L: Borrow<[T]> + 'a, 

T:

rust">T: ToString + PartialEq + Clone,

此处,T是泛型,官方定义加了约束,T是可以复制且能转为字符并且可比较的类型。而L是T的借用,且生命周期一致。

rust">selected: Option<V>,

selected是枚举,枚举的类型是V:

rust">V: Borrow<T> + 'a,

与options不同的是,V借用T,而L借用的是数组[T].

rust">on_select: Box<dyn Fn(T) -> Message + 'a>, 

on_select是和事件绑定的,是消息的触发,它被定义为一个指针,指向的是pick_list的选项,并接收反馈的消息内容。综合起来,Box<dyn Fn(T) -> Message + 'a> 表示一个指向实现了Fn(T) -> Message trait的对象的堆上分配的智能指针,且这个对象的生命周期至少为’a。
以上是关于官方定义的解释,下面我们来看一下实际应用。

rust">pick_list(&Item::ALL[..],self.selected_item,Message::ItemSelected)           

此处,&Item::ALL[…]对应的是options,selected对应的是self.selected_item,而on_select对应的是Message::ItemSelected。
分别来看一下各个变量是如何创建的。

先创建了枚举Item,此处为其添加了Default特性。

rust">#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]  
enum Item{#[default]Rust,Elm,Ruby,Haskell,C,JS,Other,}

然后,Item作为pick_list的选项的数据,其必须符合定义时泛型T的定义:

rust">T: ToString + PartialEq + Clone, 

T可以转为字符,所以,我们需要为Item实现Display特性:

rust">impl std::fmt::Display for Item{      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {write!(f,"{}",match self{Item::Rust => "Rust",Item::Elm => "Elm",Item::Ruby => "Ruby",Item::Haskell => "Haskell",Item::C => "C",Item::JS => "Javascript",Item::Other => "Other",})}
}

Display可以很方便的设置参数转为字符的格式化设置。
而为了使Item的选项能够作为数组[T]传入options,需要将Item实现数组定义:

rust">impl Item{    const ALL:[Item;7]=[Item::Rust,Item::Elm,Item::Ruby,Item::Haskell,Item::C,Item::JS,Item::Other,];
}

此处定义了一个常量ALL,ALL包含了Item的所有项,且是数组。
而selected的参数selected_item 则定义在结构体中:

rust">struct Example{ value:i64,value_sld:f32,value_sld2:f32,default:f32,step:f32,shift_step:f32,selected_item:Option<Item>,
}

注意selected_item的类型是枚举。
而on_select的参数则是消息:

rust">#[derive(Debug,Clone,Copy)]
enum Message{Clicked,SliderChanged(f32),ItemSelected(Item),
}

这样一来,Item中定义的项,将会按照Display设置的显示格式,显示在下拉列表中:
在这里插入图片描述
当我们选择其中一项时,会触发on_select,此时,选中的项的内容将作为消息传递给Message::ItemSelected(Item),其中item就是选中项。
我们只需要在update函数中处理消息即可:

rust">  fn update(&mut self,message:Message){      match message{Message::Clicked => {self.value +=1;}    Message::SliderChanged(value)=>{self.value_sld=value;}Message::ItemSelected(item)=>{self.selected_item=Some(item);println!("{:?}",item);}}}

可以看到,我们将选中项作为值赋给了变量selected_item,也就是只要我们选择任何项,selected_item都会跟随改变,也就是下拉列表选择完成后显示的就是我们选择的项。
我们也可以将selected_item 赋予其他部件,如text,这样我们选择什么项,就可以在UI上显示出来:
在这里插入图片描述  
综上,我们已经基本了解了pick_list作为小部件是如何定义和使用的,其属性和参数又是如何设置的。
下面看一下动态演示:
在这里插入图片描述


http://www.ppmy.cn/devtools/24477.html

相关文章

typeScript 安装

1、安装typescript 安装npm i -g typescript 查看是否安装成功 tsc -v 2、使用ts // 浏览器不支持ts 需要编译成 es5 let str: string ts 在终端输入 tsc index.ts 会将其生成一个对应的index.js文件 在电脑上首次使用TS的时候&#xff0c;执行TS 的命令的时候报错 打开PowerS…

网际协议IP

一、概念导入 网际协议IP是TCP/IP体系中最重要的协议之一。与IP协议配套使用的还有三个协议&#xff1a; 地址解析协议ARP网际控制报文协议ICMP网际组管理协议IGMP 二、虚拟互联网络 &#xff08;1&#xff09;定义 现实世界中&#xff0c;不同网络的主机进行通信&#xf…

【matplot】【matlab】绘制简洁美观二维坐标系的一个例子

觉得下图不错美观大方&#xff0c;现仿制下图&#xff1a; import numpy as np import matplotlib.pyplot as pltdef sigmoid(x):return 1 / (1 np.exp(-x))def sigmoid_derivative(x):return sigmoid(x) * (1 - sigmoid(x))# 设置中文字体 plt.rcParams[font.family] [Tim…

JavaEE技术之MySql高级(索引、索引优化、sql实战、View视图、Mysql日志和锁、多版本并发控制)

文章目录 1. MySQL简介2. MySQL安装2.1 MySQL8新特性2.2 安装MySQL2.2.1 在docker中创建并启动MySQL容器&#xff1a;2.2.2 修改mysql密码2.2.3 重启mysql容器2.2.4 常见问题解决 2.3 字符集问题2.4 远程访问MySQL(用户与权限管理)2.4.0 远程连接问题1、防火墙2、账号不支持远程…

论文阅读_股票预测强化学习_StockFormer

1 StockFormer PLAINTEXT 1 2 3 4 5 6 7中文名称&#xff1a;StockFormer: 混合交易机与预测编码 英文名称&#xff1a;StockFormer: Learning Hybrid Trading Machines with Predictive Coding 作者&#xff1a;Siyu Gao, Yunbo Wang∗, and Xiaokang Yang 机构&#xff1a;M…

React面试题(一)

react的优缺点 优点 虚拟DOM&#xff1a;减少对真实DOM的操作&#xff0c;提高性能。组件化&#xff1a;将代码分成一个个小的、可复用的组件&#xff0c;利于管理、维护。使用JSX&#xff1a;在React中可以嵌入HTML和JavaScript。单向数据流&#xff1a;React的单向数据流使得…

发那科FANUC机器人R-2000iB平衡缸维修攻略

在发那科机器人中&#xff0c;平衡缸扮演着稳定机械臂运动的关键角色。它通过内部的压力调节来平衡负载&#xff0c;保证机器人的精准定位和平稳操作。一旦出现法兰克机械手平衡缸故障或损坏&#xff0c;机器人的性能可能会大打折扣&#xff0c;因此及时且正确的FANUC机械手平衡…

【Python】如何使用Python和keyboard库解决内网字符无法复制到外网的问题

但我的心每分每刻仍然被她占有 她似这月儿仍然是不开口 提琴独奏独奏着明月半倚深秋 我的牵挂我的渴望 直至以后 &#x1f3b5; 李克勤《月半小原夜曲》 在一些特定的工作环境中&#xff0c;可能会存在内网与外网隔离的情况&#xff0c;这意味着直接的数据…

基于深度学习的SAR图像舰船检测方案设计

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 项目简介&#xff1a;基于深度学习的SAR图像舰船检测方案设计 本项目旨在设计一种基于深度学习的SAR图像舰船检测方…

深入理解Python多进程:从基础到实战

title: 深入理解Python多进程&#xff1a;从基础到实战 date: 2024/4/29 20:49:41 updated: 2024/4/29 20:49:41 categories: 后端开发 tags: 并发编程多进程管理错误处理资源调度性能优化异步编程Python并发库 引言 在Python编程中&#xff0c;多进程是一种重要的并发编程…

Kafka 3.x.x 入门到精通(03)——Kafka基础生产消息

Kafka 3.x.x 入门到精通&#xff08;03&#xff09;——对标尚硅谷Kafka教程 2. Kafka基础2.1 集群部署2.2 集群启动2.3 创建主题2.4 生产消息2.4.1 生产消息的基本步骤2.4.2 生产消息的基本代码2.4.3 发送消息2.4.3.1 拦截器2.4.3.1.1 增加拦截器类2.4.3.1.2 配置拦截器 2.4.3…

FreeBSD安装Miniconda,python启动core dumped的问题

综述&#xff1a; 学会在FreeBSD安装Miniconda后&#xff0c;在一台服务器上安装却碰到问题&#xff0c;安装好后&#xff0c;执行python报错&#xff1a;Segmentation fault (core dumped) 。 以前成功的是在FreeBSD13版本&#xff0c;报错的这个是FreeBSD14版本&#xff0c…

22 - Hadoop HA 高可用集群搭建、手动模式、自动模式以及HA模式集群

目录 1、HA 概述 2、HDFS-HA 集群搭建 2.1、HDFS-HA 核心问题 3、HDFS-HA 手动模式 3.1、环境准备 3.2、规划集群 3.3、配置 HDFS-HA 集群 3.4、启动 HDFS-HA 集群 4、HDFS-HA 自动模式 4.1、HDFS-HA 自动故障转移工作机制 4.2、HDFS-HA 自动故障转移的集群规划 4.…

ThreeJs模拟工厂生产过程八

这节算是给这个车间场景收个尾&#xff0c;等了几天并没有人发设备模型给我&#xff0c;只能自己找了一个凑合用了。加载模型之前&#xff0c;首先要把货架上的料箱合并&#xff0c;以防加载模型之后因模型数量多出现卡顿&#xff0c;方法和之前介绍的合并传送带方法相同&#…

用OpenCV先去除边框线,以提升OCR准确率

在OpenCV的魔力下&#xff0c;我们如魔法师般巧妙地抹去表格的边框线&#xff0c;让文字如诗如画地跃然纸上。 首先&#xff0c;我们挥动魔杖&#xff0c;将五彩斑斓的图像转化为单一的灰度世界&#xff0c;如同将一幅绚丽的油画化为水墨画&#xff0c;通过cv2.cvtColor()函数的…

Photoshop前言

Photoshop前言 分辨率图像格式工具界面组件 分辨率 分辨率是指单位长度内包含的像素点的数量&#xff0c;其单位通常为像素/英寸&#xff08;ppi&#xff09;&#xff0c;300ppi表示每英寸包含300个像素点。对于1英寸1英寸大小的图像&#xff0c;若分辨率为72ppi&#xff0c;则…

【 深度可分离卷积】

深度可分离卷积 深度可分离卷积&#xff08;Depthwise Separable Convolution&#xff09;是一种在卷积神经网络中减少计算量和参数数量的技术。这种技术将标准的卷积操作分解为两个更简单的操作&#xff1a;逐通道卷积&#xff08;Depthwise Convolution&#xff09;和逐点卷…

Xshell不能使用(版权原因不能使用),通过ip连接虚拟机CentOS7系统拷贝文件

一、使用SSH服务 1.确保 CentOS 7 虚拟机安装了 SSH 服务。 systemctl status sshd 如果没有安装&#xff0c;您可以使用以下命令来安装&#xff1a; sudo yum install openssh-server 2.启动 SSH 服务&#xff08;如果尚未启动&#xff09;&#xff1a; sudo systemctl …

自动驾驶中的深度学习和计算机视觉

书籍&#xff1a;Applied Deep Learning and Computer Vision for Self-Driving Cars: Build autonomous vehicles using deep neural networks and behavior-cloning techniques 作者&#xff1a;Sumit Ranjan&#xff0c;Dr. S. Senthamilarasu 出版&#xff1a;Packt 书籍…

LXC的原理及应用详解(二)

本系列文章简介&#xff1a; 在信息化时代&#xff0c;虚拟化技术以其独特的优势&#xff0c;正逐渐成为推动信息技术发展的重要力量。其中&#xff0c;Linux容器&#xff08;Linux Containers&#xff0c;简称LXC&#xff09;作为一种轻量级的虚拟化技术&#xff0c;正日益受到…