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;
    }
}

编译运行后的界面如下:
image
目前我们发现Slint实现标题栏图标的替换,比我们前期尝试过的egui/eframe要方便多了。那么如果要实现界面中的中文是否也是如此呢?尝试将代码中的Text控件中的文本替换成中文。并编译运行,结果如下:
image
发现当前版本的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;
    }
}

为了清晰地看出字体的改变,故把字体字号调大,现在的界面效果为:
image
使用同样的方法,我们再换一个英文的字体,看一看效果:
image
由此,我们发现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对技术结果进行输出。
现在编译运行后的界面如下:
image
经过初步试用,我们已经发现Slint框架非常易于上手,各项功能非常易用。本次我们还并没有使用回调函数在slint文件和rs文件中进行交互。下一次我们将在这方面进行探索。

posted @ 2024-01-09 15:36  AbsalomT  阅读(470)  评论(0编辑  收藏  举报