[rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(01):为窗口设置布局(column、row)

前言

本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发。

iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动。

本合集是基于新版本的关于分部件(widget)的使用介绍,包括源代码介绍、实例使用等。

环境配置

系统:window10

平台:visual studio code

语言:rust

库:iced 0.13

iced布局简介

iced中用于布局的部件有column、row等,我们在之前的博文里的示例代码中,就使用了column布局,也就是纵向排列的布局。同样,顾名思义,row即是横向布局。

二者可以嵌套使用,形成纵、横布局。

1、column布局

在iced中的定义就是:

//! Distribute content vertically.

创建一个column布局有几种方式,在我们前文的示例中,使用了column!这样的方式,这是一个快捷的方式,属于iced官方定义的一个宏macro:

官方源码
rust 复制代码
#[macro_export]
macro_rules! column {
    () => (
        $crate::Column::new()
    );
    ($($x:expr),+ $(,)?) => (
        $crate::Column::with_children([$($crate::core::Element::from($x)),+])
    );
}

这个宏可以直接创建一个Column实例,也可以根据传入的子项来创建Column实例。

以前文代码为例:

rust 复制代码
column![
            button("增加Inc").on_press(Message::Inc),
            text(self.count).size(20),
            button("减少Dec").on_press(Message::Dec)
        ]

此处,我们创建了一个column,并在其中添加了两个按钮和一个text,它们将在窗口呈纵向排列,我们可以通过设置column的spacing属性来调整其中元素之间的间隙。

将spacing设置为10:

我们可以来看一下Column的官方结构体定义:

官方源码
rust 复制代码
pub struct Column<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
{
    spacing: f32,
    padding: Padding,
    width: Length,
    height: Length,
    max_width: f32,
    align: Alignment,
    clip: bool,
    children: Vec<Element<'a, Message, Theme, Renderer>>,
}

可以看到,其参数中,大部分是属性设置,其中children用于设置传入的子元素,也就是你希望在当前窗口某部分程序纵向排列的子元素,可以是任何widget,也可以嵌套布局,如column、row。

比如,我们将前文的按钮、文本的布局设为row,然后再嵌入到column中:

rust 复制代码
let row1=row![
            button("增加Inc").on_press(Message::Inc),
            text(self.count).size(20),
            button("减少Dec").on_press(Message::Dec)
        ].spacing(10).padding(20);
        column![
           row1,
        ].spacing(10).padding(20)
        .align_x(iced::Center)
        .into()

看下效果:

我们多增加一些部件和嵌套:

rust 复制代码
let row1=row![
            button("增加Inc").on_press(Message::Inc).width(60),
            text(self.count).size(20),
            button("减少Dec").on_press(Message::Dec).width(60)
        ].spacing(10).padding(20).width(200).height(100);
        let col1=column![
            button("col1").width(60).on_press(Message::None),
            text("col1").size(12),
            button("col1").width(60).on_press(Message::None),
        ].spacing(10).padding(5);
        
        let color1=iced::Color::from_rgba(155.0,0.0,0.0,255.0);
        let cont_row=container(col1)
                                        .style(move |t|styles::mycontainerstyle(t,color1))
                                        .width(100).height(200)
                                        .align_x(iced::Center).align_y(iced::Center);
        let col2=column![
            text("col2").size(12),
        ];
        let color2=iced::Color::from_rgba(0.0,155.0,0.0,255.0);
        let cont_row2=container(col2)
                                        .style(move |t|styles::mycontainerstyle(t,color2))
                                        .width(100).height(200)
                                        .align_x(iced::Center).align_y(iced::Center);
        let col3=column![
            text("col3").size(12),
        ];
        let color3=iced::Color::from_rgba(0.0,0.0,155.0,255.0);
        let cont_row3=container(col3)
                                        .style(move |t|styles::mycontainerstyle(t,color3))
                                        .width(100).height(200)
                                        .align_x(iced::Center).align_y(iced::Center);
        let row_col=row![
            cont_row,cont_row2,cont_row3
        ].spacing(10).padding(20).height(200);
        column![
           row1,
           row_col,
        ].spacing(10).padding(20)
        .align_x(iced::Center)
        .into()

仔细看一下上面的代码,我们在原先的基础上,添加嵌套布局,总体布局是纵向,纵向有两层,第一层是原先的部件,第二层我们又嵌套了横向布局,一共三列,每一列又嵌套了纵向,为了显示区别,我们添加了背景色,其中关于style的使用,本文不做赘述。

看一下效果:

注意图片中的红黄蓝区域,此处我使用了container部件,方便设置背景色,以作区别。

当然,上面的布局看起来可能不是很整齐,但是实现的效果是对的,即column和row的嵌套来实现页面的布局,可以通过设置spacing和padding来微调部件的位置。

下面,我调整一下代码,为了使布局看起来更简洁有效,我们将显示一个按钮九宫格布局,那么就是三列或者三行互相嵌套,而且其中的子元素都是按钮,且居中排布。

先修改一下代码:

rust 复制代码
let col1=column![
            button(text("col1_1").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col1_2").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col1_3").size(15)).width(80).height(40).on_press(Message::None),
        ].spacing(10);
        
        // let color1=iced::Color::from_rgba(155.0,0.0,0.0,255.0);
        // let cont_row=container(col1)
        //                                 .style(move |t|styles::mycontainerstyle(t,color1))
        //                                 .width(100).height(200)
        //                                 .align_x(iced::Center).align_y(iced::Center);
        let col2=column![
            button(text("col2_1").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col2_2").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col2_3").size(15)).width(80).height(40).on_press(Message::None),
        ].spacing(10);
        // let color2=iced::Color::from_rgba(0.0,155.0,0.0,255.0);
        // let cont_row2=container(col2)
        //                                 .style(move |t|styles::mycontainerstyle(t,color2))
        //                                 .width(100).height(200)
        //                                 .align_x(iced::Center).align_y(iced::Center);
        let col3=column![
            button(text("col3_1").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col3_2").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col3_3").size(15)).width(80).height(40).on_press(Message::None),
        ].spacing(10);
        // let color3=iced::Color::from_rgba(0.0,0.0,155.0,255.0);
        // let cont_row3=container(col3)
        //                                 .style(move |t|styles::mycontainerstyle(t,color3))
        //                                 .width(100).height(200)
        //                                 .align_x(iced::Center).align_y(iced::Center);
        let row_col=row![
            col1,col2,col3
        ].spacing(10).padding(2).align_y(iced::Center);
        // column![
        //    //row1,
        //    row_col,
        // ].spacing(10).padding(20)
        // .width(300).height(300)
        // .align_x(iced::Center)
        // .into()
        let cont=container(row_col)
                                .align_x(iced::Center).align_y(iced::Center)
                                .width(300).height(300);
        cont.into()

上面的布局,有一些代码是之前的代码,但是被注释了,不用管它,我们只关注有效代码,修改后的代码显示的效果如下;

2、row布局

row布局与column布局是完全一样的,除了布局方向,所以就不再赘述了。

3、综述

column和row是iced中常见的布局,但是并不是唯一,iced还有其他可以实现布局的方式,但本文不再赘述,将在后续逐渐展开。

综合本文上述的介绍,哪怕只是使用column和row,经过调整之后,也是能做出比较好看的布局的,当然以上只涉及了布局,还没有仔细去设置样式,包括边框、颜色、阴影等这些样式,这些都将在后续博文中介绍。

相关推荐
flying robot15 小时前
Rust的对web生态的影响
开发语言·前端·rust
WPG大大通19 小时前
加速物联网HMI革命,基于TouchGFX的高效GUI显示方案
stm32·mcu·物联网·gui·工业·hmi·大大通
m0_748239631 天前
从零开始的vscode配置及安装rust教程
ide·vscode·rust
快乐非自愿1 天前
一文解秘Rust如何与Java互操作
java·开发语言·rust
SomeB1oody1 天前
【Rust自学】10.8. 生命周期 Pt.4:方法定义中的生命周期标注与静态生命周期
开发语言·后端·rust
许野平1 天前
Rust:运行调用 Lua 脚本
rust·lua·rlua
Source.Liu1 天前
【学Rust开发CAD】1 环境搭建
开发语言·rust
Source.Liu1 天前
【学Rust开发CAD】2 创建第一个工作空间、项目及库
rust·cad
SomeB1oody1 天前
【Rust自学】9.3. Result枚举与可恢复的错误 Pt.2:传播错误、?运算符与链式调用
开发语言·前端·rust