0


【一起学Rust | 框架篇 | Frui框架】rust一个对开发者友好的GUI框架——Frui

文章目录


前言

本次内容接上回《rust原生跨平台GUI框架——iced》,最近突然涌现出多个Rust的UI框架,真实令人兴奋,同时也突出了Rust的勃然生机,我将尽量为大家介绍Rust领域的UI框架,带大家体验Rust领域的好玩意儿。

Frui是一个对开发者相当友好的UI框架,它使得开发者构建用户界面变得简单,并且是一个真正意义上受Flutter启发、用纯Rust写的UI框架。如果你了解Flutter,或者Vue/React的话,学习这些东西将会变得很容易,但是如果你并不了解,还是建议你去学习基础内容,并且推荐一本书《Flutter实战·第二版》,读者可以在Github上自行搜索。本期内容还是老规矩,写个Counter的Demo来看看。

由于Frui现在刚发行第一版,所以要求不是很高,本期内容主要体验其编码方式。


一、新建项目

1. 创建项目

这里依旧还是我们的老规矩,创建一个Counter的Demo项目。

cargo new gui_frui_001

2. 导入idea

使用idea打开刚才创建的项目

3. 引入依赖

Cargo.toml

中导入依赖

frui = "0.0.1"

4. 执行案例代码

将以下代码复制到

main.rs
#![feature(min_specialization)]#![feature(type_alias_impl_trait)]usefrui::prelude::*;#[derive(ViewWidget)]structApp;implViewWidgetforApp{fnbuild<'w>(&'wself, _:BuildContext<'w,Self>)->Self::Widget<'w>{Center::child(Text::new("Hello, World!"))}}fnmain(){run_app(App);}

然后idea就会报错

因为我用的是稳定版的Rust,因此一些特性是没有的,所以要安装nightly版本的Rust,直接执行以下代码

rustup toolchain install nightly

然后列出当前Rust的版本

rustup toolchain list

现在激活

nightly

版本的编译器

rustup default nightly

接下来去项目目录覆盖配置文件

rustup override set nightly

此时idea还会提示错误的,这是因为nightly没有源码,插件默认用的stable的源码,所以检查语法出错了,不必管他,直接运行

如果你也运行了下面的窗口,说明你已经配置成功了。

二、实现计数器Demo

1.导入资源

在实现Counter Demo之前,我们需要导入框架所需要的资源,我发现其框架并未打包UI相关的资源,要是和Flutter那样可以直接用Material的UI就太好了,我觉得以后可能会出类似的。

首先需要从Github上的

frui-main\examples

复制出

misc

文件夹到我们项目的目录来,

可以看到这个版本目前只提供了按钮和开关,还有State,到现在为止,框架相关的内容都已经导入完毕。

2.编写窗口代码

Frui的代码和Flutter是高度相似的,从编写窗口代码这里就可以看出来。首先要做的就是先定义窗口State,这里我们定义了CrabCounter,并且实现WidgetState,并且给一个整数型的State,特别重要的是一定要写create_state方法,初始化State。

#[derive(ViewWidget)]structCrabCounter;implWidgetStateforCrabCounter{typeState=isize;fncreate_state(&self)->Self::State{0}}

接下来就是要编写窗口,实现窗口逻辑。在这里给Crab Counter实现了ViewWidget特质,其必须要实现一个build方法,返回构建的窗口,其代码如下

implViewWidgetforCrabCounter{fnbuild<'w>(&'wself, ctx:BuildContext<'w,Self>)->Self::Widget<'w>{Column::builder().space_between(60.0).main_axis_size(MainAxisSize::Max).cross_axis_size(CrossAxisSize::Max).main_axis_alignment(MainAxisAlignment::Center).cross_axis_alignment(CrossAxisAlignment::Center).children((Text::new(format!("{} 🦀",*ctx.state())).size(100.0).weight(FontWeight::BOLD),Row::builder().space_between(10.0).children((Button{
                            label:Text::new("+").size(30.),
                            on_click:||*ctx.state_mut()+=1,},Button{
                            label:Text::new("-").size(30.),
                            on_click:||*ctx.state_mut()-=1,},)),))}}

以上代码的布局是这个样子的
要注意的是,Button 至少需要传入两个参数,一个是按钮的标签——Text,当然也可以是Image,目前并不清楚它是否有这个组件了,所以还是按官方的来,直接用Text;一个是点击的回调函数,

3. 运行效果

此时我们运行Counter程序,如果运行没有错误,那应该是下面这个样子的
上面的Text部分,左边是计次的数字,右边是Rust的吉祥物🦀,下面是两个按钮,一个+,一个-

Rust的吉祥物是🦀,而非图中白色的样子,官方给出的运行结果应该是下面这个样子的
Rust是支持这种文本的,但是不知道为什么表现出来和官方给的案例是不一样的。


总结

本期学习了另一个由纯Rust写的UI框架——Frui,这是一个对开发者相当友好的框架,借鉴于Flutter,可惜是刚起步的框架,相信其在以后的发展肯定会变得更好。

Frui框架的路子是学习Flutter的,其代码也是高度相似,代码也容易理解,确实做到了对开发人员友好,这是非常值得肯定的,学习过Flutter的人甚至可以直接迁移过来,不需要学习太多的内容,降低了学习成本。但是该项目还处在刚开始阶段,我觉得可以关注一手,该框架如果做完,可能是Rust的主流框架。此外,这个Counter还不支持点关闭按钮来关闭窗口,我觉得这可能是因为没有实现关闭按钮的代码导致的,后续随着该项目的发展,会补齐这部分内容。

比较起上期的UI框架——Iced,其架构思想与Flutter也是高度相似,与Frui不同的是,Iced主要借助于一个Sandbox,但是其编程手法是对开发者比较有好的。在我的体验中,主要遇到的是文档版本错乱,不支持中文,所以导致体验很差。我在别的博主下面看到Iced是支持中文的,但是我加中文就乱码,目前还不清楚是什么问题。

完整代码

counter的完整代码

usefrui::prelude::*;userand::Rng;/// This widget will display a different number every time its state is lost.#[derive(ViewWidget)]pubstructRandomState;implWidgetStateforRandomState{typeState=usize;fncreate_state<'a>(&'aself)->Self::State{rand::thread_rng().gen()}}implViewWidgetforRandomState{fnbuild<'w>(&'wself, ctx:BuildContext<'w,Self>)->Self::Widget<'w>{Text::new(ctx.state().to_string())}}/// This widget will display a different number every time it gets rebuilt.#[derive(ViewWidget)]pubstructChangesOnRebuild;implViewWidgetforChangesOnRebuild{fnbuild<'w>(&'wself, _:BuildContext<'w,Self>)->Self::Widget<'w>{Text::new(rand::thread_rng().gen::<usize>().to_string())}}

此处附上Flutter的Counter代码,读者可观察其异同,至于Flutter做开发的好处,只有当读者真正去用的时候才会体会到了。

classMyHomePageextendsStatefulWidget{constMyHomePage({Key? key, required this.title}):super(key: key);finalString title;@overrideState<MyHomePage>createState()=>_MyHomePageState();}class _MyHomePageState extendsState<MyHomePage>{
  int _counter =0;void_incrementCounter(){setState((){
      _counter++;});}@overrideWidgetbuild(BuildContext context){returnScaffold(
      appBar:AppBar(
        title:Text(widget.title),),
      body:Center(
        child:Column(
          mainAxisAlignment:MainAxisAlignment.center,
          children:<Widget>[constText('点击按钮的次数:',),Text('$_counter',
              style:Theme.of(context).textTheme.headline4,),],),),
      floatingActionButton:FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip:'Increment',
        child:constIcon(Icons.add),),);}}

本文转载自: https://blog.csdn.net/weixin_47754149/article/details/127396748
版权归原作者 广龙宇 所有, 如有侵权,请联系我们删除。

“【一起学Rust | 框架篇 | Frui框架】rust一个对开发者友好的GUI框架——Frui”的评论:

还没有评论