0


Rust UI开发(四):iced中如何添加菜单栏(串口调试助手)

注:此文适合于对rust有一些了解的朋友
iced是一个跨平台的GUI库,用于为rust语言程序构建UI界面。
在这里插入图片描述
这是一个系列博文,本文是第四篇,前三篇链接:
1、Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符
2、Rust UI开发(二):iced中如何为窗口添加icon图标
3、Rust UI开发(三):iced如何打开图片(对话框)并在窗口显示图片?

注:本篇是系列的第四篇,从本篇开始,将基于编写一个串口调试助手项目,以多个篇幅,来分别说明。
要编写一个调试助手,总的来说,可以分为UI设计、底层串口数据通讯、交互三个方面。
所以,此后数篇博文都将以“串口调试助手”项目为例,辅以各个功能的介绍说明如菜单栏如何创建、串口UI界面如何设计、串口通讯如何实现以及数据交互如何实现等,我希望最终能达到一个完整的可使用的以rust和iced为主要库构建的实例项目,可以实现与串口设备的通讯,至少能稳定实现数据交互。

本篇主要关注一个问题,就是菜单栏的创建,iced库中并没有包含menu部件,需要用到iced_aw库。github地址:
https://github.com/iced-rs/iced_aw
这是一个包含有许多额外部件的iced库,如颜色选择器、日期选择器、菜单、拆分、Tab组件等。

从本篇开始,将附加程序中用到的依赖项
Cargo.toml:

[dependencies]
iced.workspace=true
iced.features=["image","svg"]

iced_aw={
    workspace=true, features =["card","menu","quad","icon_text"]}
image.workspace=true
num-complex.workspace=true[workspace.dependencies]
iced ="0.10"
iced_aw={
    version ="0.7.0", default-features =false}

image="*"
num-complex="*"

项目文件结构:
在这里插入图片描述

实际效果预览:
在这里插入图片描述

声明:本篇参考iced_aw的官方关于menu的示例,但作了一些修改,以适应自定义项目的所需,所以,如果想要了解iced_aw源代码的,建议去参看官方示例。

关于iced如何构建窗口,以及窗口设置、图标设置等内容,可以看本系列前三篇,本篇主要实现这样的功能,创建菜单栏,当选择某个菜单项时,文本框中显示当前选择的菜单项名称。

菜单栏创建

1、添加依赖
参看前面的toml文件。

2、程序里导入

useiced_aw::menu::{
   menu_tree::MenuTree,CloseCondition,ItemHeight,ItemWidth,PathHighlight};useiced_aw::quad;useiced_aw::{
   helpers::menu_tree, menu_bar, menu_tree};

其中有一些是本篇内容没有用到的,删掉也可以,不删也没关系,不影响程序的测试。

3、menu部件创建
iced_aw的官方示例中,关于menu的创建,看起来比较复杂,原因是功能做的比较丰富,但如果不需要那么多功能,则可以对其进行修改。
官方示例程序,是层层递进的结构,并且写的复杂,是因为要设置菜单的样式、菜单的反馈对应的动作等。
但是,我们可以从简单的先来看,如果你只是要在窗口上实现一个菜单栏,那么:

menu_bar!(menu_tree!(button("文件")))

这个就可以实现,当然这样实现的菜单没有任何功能,也没有样式的变化。它就是在窗口创建了一个菜单项。
在这里插入图片描述
上图可以看到,这样创建的无样式的菜单项和旁边设置了主题样式的菜单项,有明显区别。
事实上,在这里的菜单项,就是一个个的按钮组成。通过设置按钮的样式,就可以改变菜单的样式。
所以,在官方示例中,是创建了一个ButtonStyle结构体:

structButtonStyle;

然后,将button部件的StyleSheet特性实现于创建的结构体ButtonStyle上:

implbutton::StyleSheetforButtonStyle{
   typeStyle=iced::Theme;//生成按钮的激活外观fnactive(&self, style:&Self::Style)->button::Appearance{
   button::Appearance{
   
            text_color: style.extended_palette().background.base.text,
            border_radius:[2.0;4].into(),
            background:Some(Color::TRANSPARENT.into()),..Default::default()}}//生成按钮的悬停外观fnhovered(&self, style:&Self::Style)->button::Appearance{
   let plt = style.extended_palette();button::Appearance{
   
            background:Some(plt.primary.weak.color.into()),
            text_color: plt.primary.weak.text,
            border_radius:[6.0;4].into(),//border_radius:倒角半径..self.active(style)}}}

上面的实现中,启用了button部件的active和hovered两个功能,这两个功能是当我们将鼠标放在按钮上悬停以及激活按钮时,按钮的样式会按照设定的程序来变化。可以看到,其中改变的是文本颜色、背景色以及部件的四边的倒角。
基于这个按钮样式数据ButtonStyle,我们可以创建一个基础按钮base_button:

//基础按钮fnbase_button<'a>(
    content:implInto<Element<'a,Message,iced::Renderer>>,
    msg:Message,)->button::Button<'a,Message,iced::Renderer>{
   button(content).padding([4,8]).style(iced::theme::Button::Custom(Box::new(ButtonStyle{
   }))).on_press(msg)}

在base_button的基础上,创建带标签按钮labeled_button:

//带标签按钮fnlabeled_button<'a>(label:&str, msg:Message)->button::Button<'a,Message,iced::Renderer>{
   base_button(text(label).width(Length::Fill).height(Length::Fill).vertical_alignment(alignment::Vertical::Center),
        msg,)}

然后创建测试按钮debug_button:

//测试按钮fndebug_button<'a>(label:&str)->button::Button<'a,Message,iced::Renderer>{
   labeled_button(label,Message::InputChanged(label.into()))}

最后,在菜单项中调用这个有样式设定的按钮即可:

fndebug_item<'a>(label:&str)->MenuTree<'a,Message,iced::Renderer>{
   menu_tree!(debug_button(label).width(Length::Fill).height(Length::Fill))}

以上,都是官方示例给出的步骤,它是用函数块的形势,将每一步分解,这样方便多次调用,以及对某个涉及到的项进行动态更改。
但是,如果你不想这样多次,就想一个函数实现菜单项功能,那么可以自己重新写一个函数:

///简单的菜单调用fnmenu_simple<'a>(label:&str,_app:&Counter)->MenuTree<'a,Message,iced::Renderer>{
   menu_tree(button("haha").padding([4,8]).style(iced::theme::Button::Custom(Box::new(ButtonStyle{
   }))).on_press(Message::InputChanged(label.into())),vec![//debug_item("label"),menu_tree!(text("haha"))])}

可以看到,在我们自定义的函数里,使用menu_tree,可以直接创建菜单和子菜单,但数量少时还可以,数量多了,写在一个函数里,就不太方便了。
在这里插入图片描述
这里,我们在自定义函数里只是简单的编写了一些程序,目的是演示,如果去编写实际项目,建议按照官方示例的模板,因为那样写比较有清晰的结构。

现在,我们了解如何创建菜单,接下来响应菜单。其实这里就比较容易了,因为菜单是由一个个button这样的小部件组成的,只需要监控小部件的触发函数,就可以在交互中传回消息。以我们自定义的函数为例,菜单中button的on_press函数,绑定了消息参数:InputChanged,InputChanged附带一个String类型的返回值。

button("haha").padding([4,8]).style(iced::theme
标签: rust ui 开发语言

本文转载自: https://blog.csdn.net/normer123456/article/details/134649667
版权归原作者 机构师 所有, 如有侵权,请联系我们删除。

“Rust UI开发(四):iced中如何添加菜单栏(串口调试助手)”的评论:

还没有评论