热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

rust语言orbtkGUI入门3.1orbtk基础控件

rustorbtk基础widgetsorbtk基础控件demoorbtk控件使用方法orbtk控件原理创建控件为控件添加子控件设置属性添加状态和事件处理器render设置控件外观通

rust orbtk基础widgets

  • orbtk基础控件demo
  • orbtk控件使用方法
    • orbtk控件原理
    • 创建控件
      • 为控件添加子控件
      • 设置属性
      • 添加状态和事件处理器
      • render设置
      • 控件外观
    • 通用属性
    • TextBlock控件主要属性
    • WaterMarkTextBlock控件
    • textbox
    • button
    • checkbox
    • switch
    • image
    • FontIconBlock
  • 本文代码

orbtk基础控件demo

orbtk目前内置的控件并不多,基础控件主要有:

  • TextBlock
  • TextBox
  • Button
  • ToggleButton
  • check_box
  • Switch
  • FontIconBlock
  • ImageWidget
  • WaterMarkTextBlock//貌似目前(2019.1)还有问题,不能正常显示

首先,我们先创建一个包含基础控件的窗口,看看效果:

use orbtk::*;
use styling::vector_graphics::material_font_icons::CHECK_FONT_ICON;

fn main() {
    let mut application = Application::default();

    //创建控件
    let text_block = TextBlock::create().with_property(Label::from("textblock"));
    let text_box = TextBox::create().with_property(Label::from("textbox"));
    let water_mark_text_box = TextBox::create().with_property(WaterMark::from("watermark..."));
    let btn = Button::create().with_property(Label::from("button"));
    let toggle_btn = ToggleButton::create().with_property(Label::from("togglebutton"));
    let switch = Switch::create();
    let check_box = CheckBox::create().with_property(Label::from("checkbox"));
    let font_icon_block = FontIconBlock::create().with_property(FontIcon::from(CHECK_FONT_ICON));
    let image_widget = ImageWidget::create()
        .with_property(Image::from_path("src/bin/img/home.png").unwrap_or(Image::default()));
    let water_mark_text_block = TextBlock::create()
        .with_property(Label::from(""))
        .with_property(WaterMark::from("textblockmark..."));
    let water_mark_text_block2 = WaterMarkTextBlock::create()
        .with_property(Label::from(String::new()))
        .with_property(WaterMark::from("yyyy..."));

    //所有控件放入Row布局控件中
    //直接把所有控件加入rootde Template控件会重叠
    //所以把所有控件都放在一个layout控件中
    let column = Column::create()
        .with_child(text_block)
        .with_child(text_box)
        .with_child(water_mark_text_box)
        .with_child(btn)
        .with_child(toggle_btn)
        .with_child(switch)
        .with_child(check_box)
        .with_child(font_icon_block)
        .with_child(image_widget)
        .with_child(water_mark_text_block)
        .with_child(water_mark_text_block2);

    //rootde parent_tyep可以设置为Multi,但是控件会重叠
    //所以初学者,建议root就设置为single,root只放一个layout控件
    let root = Template::default()
        .as_parent_type(ParentType::Single)
        .with_child(column);

    application
        .create_window()
        .with_bounds(Bounds::new(100, 100, 320, 260))
        .with_title("OrbTk - Widgets")
        .with_resizable(true)
        .with_root(root)
        //.with_debug_flag(true)
        .build();
    application.run();
}

当然,上述代码只是为了方便入门学习,可以用更加Rustacean的方式写代码:

use orbtk::*;
use styling::vector_graphics::material_font_icons::CHECK_FONT_ICON;

struct MainView;

impl Widget for MainView {
    fn create() -> Template {
        Template::default()
            .as_parent_type(ParentType::Single)
            .with_child(
                Column::create()
                    .with_child(TextBlock::create().with_property(Label::from("textblock")))
                    .with_child(TextBox::create().with_property(Label::from("textbox")))
                    .with_child(TextBox::create().with_property(WaterMark::from("watermark...")))
                    .with_child(Button::create().with_property(Label::from("button")))
                    .with_child(ToggleButton::create().with_property(Label::from("togglebutton")))
                    .with_child(Switch::create())
                    .with_child(CheckBox::create().with_property(Label::from("checkbox")))
                    .with_child(
                        FontIconBlock::create().with_property(FontIcon::from(CHECK_FONT_ICON)),
                    )
                    .with_child(ImageWidget::create().with_property(
                        Image::from_path("src/bin/img/home.png").unwrap_or(Image::default()),
                    ))
                    .with_child(
                        TextBlock::create()
                            .with_property(Label::from(""))
                            .with_property(WaterMark::from("textblockmark...")),
                    )
                    .with_child(
                        WaterMarkTextBlock::create()
                            .with_property(Label::from(String::new()))
                            .with_property(WaterMark::from("yyyy...")),
                    ),
            )
    }
}

fn main() {
    let mut application = Application::default();

    application
        .create_window()
        .with_bounds(Bounds::new(100, 100, 320, 260))
        .with_title("OrbTk - Widgets")
        .with_resizable(true)
        .with_root(MainView::create())
        //.with_debug_flag(true)
        .build();
    application.run();
}

cargo run编译运行后显示窗口如下:

rust语言orbtk GUI入门-3.1 orbtk基础控件

orbtk控件使用方法

orbtk控件原理

orbtk所有控件的定义都是空结构体,即:

pub struct TextBlock;
pub struct Button;
pub struct Row;

orbtk所有控件都实现了Widget trait,并且目前所有控件都只实现了这一个trait。Widget trait也只有一个方法create()。

impl Widget for TextBlock {
    fn create() -> Template {
        ...
    }
    
impl Widget for Row {
    fn create() -> Template {
        ...
    }

也就是说目前所有orbtk控件都只包含一个create方法。这个create方法返回一个Template。创建控件的时候事实上就是使用create方法创建一个Template。我们可以看到上节代码中使用Button::create(),TextBox::create()等等创建控件。

设置控件属性也是使用Template的with_property()方法来设置的。所有的控件都是Template的实例,只是不同控件的属性及默认render不同。每个orbtk控件都在create()方法中设置了默认的render,orbtk绘制窗口的时候调用默认的render根据Template的属性绘制控件树。

orbtk自定义控件,就相当于新建一个Template并设置相关属性。难点主要在于render是否需要重写。

创建控件

所有的控件都使用create()方法创建,比如:

let btn=Button::create();
let text_block=TextBlock::create();

控件都通过Template的方法进行属性设置,主要包括

为控件添加子控件

使用with_child()方法添加子控件,比如:

Row::create().with_child(btn);

添加多个子控件可以多次调用with_child()方法,支持链式调用。

Row::create().with_child(btn).with_child(text_block);
//也可以
let row=Row::create().with_child(btn);
let row=row.with_child(text_block)

注意helloworld节已经提到的,Template有一个parent_type成员,其值表示能够添加多少个子控件。

  • parent_type值为ParentType::None,不能添加子控件
  • parent_type值为ParentType::Single,只能添加一个子控件,如果已经有一个子控件,则覆盖/替换
  • parent_type值为ParentType::Multi,可以添加任意多个子控件

为Template控件添加子控件之前都必须先设置一下parent_type。方法为as_parent_type()

Template::default().as_parent_type(ParentType::Single)

orbtk内置的控件都有默认的parent_type值,添加子控件前不用再设置。比如TextBlock为None,Container为Single,Row为Multi。

设置属性

使用with_property()方法设置属性

btn.with_property(Label::from("button"));

可以多次调用with_property()方法多次设置属性。

大家可以看到设置属性的时候并没有提供属性的名称,Template是根据属性类型来分辨不同属性的。所以Template中不同的属性都是不同的类型。

这也就是为什么Button在设置Label属性的时候不直接使用String,而使用一个Label结构把String包装起来的原因。Label的定义事实上就是pub struct Label(pub String)

Template还有一个with_shared_property方法,这个shared_property我们后边再讲。

添加状态和事件处理器

with_state()with_event_handler()两个方法分别用于添加状态和事件处理器,都是用于处理用户交互的,后续再讲。

render设置

with_render_object()with_layout()两个方法分别用于添加render和layout。都是和绘制控件相关的,所有orbtk内建的控件都设置了默认的render和layout,入门学习可以暂时不用管这两个方法。

控件外观

orbtk控件支持使用css样式,每个控件都可以通过设置selector属性来关联css选择器。

样式我们后续再讲讲。

通用属性

所有控件都支持的属性:

  • Bounds:设置控件位置和大小
  • Visibility:设置是否可见
  • Selector:设置css关联的选择器,class等
btn.with_property(Bounds::new(20,20,20,20));
btn.with_property(Visibility::Hidden);//控件不可见
btn.with_property(Visibility::Collapsed);//控件不可见,且不占位置
btn.with_property(
    Selector::from("button").with_class("primary")
)//css中使用button选择器,primary class定义btn的样式

TextBlock控件主要属性

TextBlock控件的功能就是现实文本,不能编辑,不能交互。

TextBlock通常只需要设置Label属性

TextBlock::create().with_property(Label::from("textblock"));

WaterMarkTextBlock控件

WaterMarkTextBlock控件类似TextBlock,但是会在Label属性为空的时候现实WaterMark属性的内容。

WaterMarkTextBlock控件主要属性包括:

  • Label
  • WaterMark
WaterMarkTextBlock::create()
    .with_property(Label::from("textblock"))
    .with_property(WaterMark::from("wartermark..."));

目前事实上TextBlock设置WaterMark属性后和watermarktextblock效果一样。
以下两种代码效果相同:

WaterMarkTextBlock::create()
    .with_property(Label::from(String::new()))
    .with_property(WaterMark::from("yyyy..."));

TextBlock::create()
    .with_property(Label::from(""))
    .with_property(WaterMark::from("textblockmark..."));

但是watermarktextblock貌似有bug,只有在WaterMarkTextBlock后方没有控件的时候才能正常显示,否则会被后方控件遮住。把WaterMarkTextBlock放在container或者Row中也会出现被裁剪的问题,大家可以试一下。

textbox

TextBox是一个文本框,可以交互输入。主要属性有

  • Label:文本框中的文字
  • WaterMark:文本框中没有文字是显示watermark
  • Focused:是否是当前控件
  • Enabled:是否可用,false时不能输入
TextBox::create()
    .with_property(WaterMark::from("watermark..."))
    .with_property(Focused(true))
    .with_property(Enabled(false))

貌似目前TextBox还不能用小键盘输入。

button

Button控件是个按钮控件,ToggleButton是一个开关型按钮。主要属性有:

  • Label:按钮上的文本
  • FontIcon:按钮上的图标
  • Pressed:是否按下
  • Enabled:是否可用
Button::create()
    .with_property(Label::from("btn"))
    .with_property(FontIcon::from(CHECK_FONT_ICON))
    .with_property(Pressed(true))
    .with_property(Enabled(false))

checkbox

checkbox的主要属性有

  • Label:文本
  • FontIcon:选中时方框内显示的图标,默认为√
  • Selected:是否选中
  • Enabled:是否可用
CheckBox::create()
    .with_property(Label::from("checkbox"))
    .with_property(FontIcon::from(FLOPPY_FONT_ICON))
    .with_property(Selected(true))
    .with_property(Enabled(true))

switch

  • PrimaryFontIcon:打开状态时的图标
  • SecondaryFontIcon:关闭时的图标
  • Selected:是否选中

属性设置方法和checkbox相同,大多数时候只需要设置Selected属性就ok了。

image

ImageWidget用于显示图片,主要属性为Image

ImageWidget::create()
    .with_property(
        Image::from_path("src/bin/img/home.png").unwrap_or(Image::default())
    )

FontIconBlock

FontIconBlock显示一个FontIcon图标,图标为font内的特殊字体。

use styling::vector_graphics::material_font_icons::{CHECK_FONT_ICON, FLOPPY_FONT_ICON};
FontIconBlock::create().with_property(FontIcon::from(CHECK_FONT_ICON))

FontIcon::from()的参数实际上是一个&str,所以可以这样用:

FontIconBlock::create().with_property(FontIcon::from(""))

本文代码

本文代码在https://github.com/hustlei/RustGuiOrbtkTutorial

可以使用下面命令编译运行

cargo run --bin widgets
cargo run --bin primitive_widgets

推荐阅读
author-avatar
小SASA的天空
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有