Rust GUI库Slint初探(一):编写.slint文件,改变图标和标题栏
在上一篇中,我们实现了用Slint创建第一个窗口:
Rust GUI库Slint初探(〇):创建一个窗口,解决缺少Qt5依赖问题
这一次我们来实现一下改变这个窗口的图标和标题栏。为此,我们要先将编写UI布局的Slint语言分离出来到一个单独的文件中。在上一篇中,我们直接使用slint::slint!宏在main.rs文件中插入了Slint语言代码。但为了实现复杂功能,这种实现方式是不现实的。
建立单独的Slint文件
现在我们建立一个单独的main.slint文件,将上一篇中的Slint代码复制进去:
export component MainWindow inherits Window {
Text {
text: "hello world";
color: green;
}
}
为了方便,暂时将main.slint文件放在了和main.rs同目录层级下,也就是在/src下。
接下来我们在cargo.toml中的[package]部分新增一行build = "build.rs"
,然后在该文件最后新增
[build-dependencies]
slint-build = "1.3.2"
随后我们在cargo.toml所在目录层级新增一个build.rs文件,并在其中写入:
fn main() {
slint_build::compile("src/main.slint").unwrap();
}
最后我们删掉原本在main.rs文件中的slint::slint!宏部分内容,并在文件开头输入slint::include_modules!();
这个时候我们可以使用cargo run来编译运行一下当前的程序了。能够得到一个和前面一样的程序界面。
自定义窗口
接下来我们开始修改main.slint来自定义这个窗口的界面。第一步,我们先改变一下这个窗口的大小,让其为固定大小的窗口。我们在MainWindow的定义中输入width: 800px;
和height: 600px;
,实现将窗口固定为800×600像素。接下来,我们使用title属性修改窗口的标题栏名称:title: "小试牛刀";
。最后我们再添加一个icon给这个窗口,前提是我们已经提前将我们的icon文件放在了main.slint同层级目录(或者其它目录,指定路径)。添加icon代码如下:icon: @image-url("icon.png");
。
完整的窗口代码自定义代码:
export component MainWindow inherits Window {
width: 800px;
height: 600px;
title: "小试牛刀";
icon: @image-url("icon.png");
Text {
text: "hello world";
color: green;
}
}
编译运行后的界面如下:
目前我们发现Slint实现标题栏图标的替换,比我们前期尝试过的egui/eframe要方便多了。那么如果要实现界面中的中文是否也是如此呢?尝试将代码中的Text控件中的文本替换成中文。并编译运行,结果如下:
发现当前版本的Slint(1.3.2)可以直接支持中文。这一点也比egui/eframe要方便多了。egui默认不支持中文是因为字体的原因,我们添加支持中文的字体后,其自然就可以支持中文了。Slint目前虽然原生支持中文,但不妨碍我们有时候想要添加新的字体来美化界面。我们也来实现一下。
首先将要添加的字体放入和main.slint同目录下(或指定其它路径),在main.slint的首行输入import "xxxx.ttf";
在Text控件的增加font-family: "xxxx";
字段。例如我这里使用的字体文件名ChillRoundGothic_Bold.ttf,字体名称为“寒蝉圆黑体”,slint代码被改写为了:
import "ChillRoundGothic_Bold.ttf";
export component MainWindow inherits Window {
height: 600px;
width: 800px;
title: "小试牛刀";
icon: @image-url("icon.png");
Text {
font-family: "寒蝉圆黑体";
font-size: 50px;
text: "你好世界";
color: green;
}
}
为了清晰地看出字体的改变,故把字体字号调大,现在的界面效果为:
使用同样的方法,我们再换一个英文的字体,看一看效果:
由此,我们发现Slint在中文支持、改变图标、改变字体等方面,都比egui/eframe要方便极多。egui在其宣称的易用性方面,也还是落后真正的成熟框架许多。
实现一个简单的功能
上面我们分别实现了两行不同的文字,如果一次将两个Text都加入窗口,而不进行布局调整,会使两行文字重叠在一起。为此我们必须使用HorizontalLayout或VerticalLayout进行布局调整。现在我们使用VerticalLayout布局把两行文字都加入窗口,并且新增一个按钮和一行新的文本,用来对按钮的按键次数进行记数。
代码如下:
import "BAUHS93.ttf";
import "ChillRoundGothic_Bold.ttf";
import { Button } from "std-widgets.slint";
export component MainWindow inherits Window {
property <int> count:0;
height: 600px;
width: 800px;
title: "小试牛刀";
icon: @image-url("icon.png");
VerticalLayout {
height: 300px;
width: 400px;
Text {
font-family: "寒蝉圆黑体";
font-size: 30px;
text: "你好世界";
color: green;
}
Text {
font-family: "Bauhaus 93";
font-size: 30px;
text: "Hello World!";
color: green;
}
Button {
text:"点击试试";
height: 50px;
width: 150px;
clicked => {count+=1;}
}
Text {
font-size: 30px;
text: "Pressed:"+count;
color: orange;
}
}
}
我们在MainWindow的定义下的第一行使用property <int> count:0
;新增了一个变量,在Button下使用clicked => {count+=1;}
方法实现了每次按下按键,对变量count自加1。最后使用一个新的Text对技术结果进行输出。
现在编译运行后的界面如下:
经过初步试用,我们已经发现Slint框架非常易于上手,各项功能非常易用。本次我们还并没有使用回调函数在slint文件和rs文件中进行交互。下一次我们将在这方面进行探索。