ITPub博客

首页 > 数据库 > 数据库开发技术 > Slint 开发介绍

Slint 开发介绍

原创 数据库开发技术 作者:Rust嵌入式 时间:2024-05-28 20:17:52 0 删除 编辑

简介

Slint 语法是一种非常容易学习的声明式语言,用于描述 GUI 界面的属性和简单的交互逻辑,能够准确清晰指定 GUI 属性,同时能够轻松阅读,因此对于设计人员和开发人员都非常友好, Slint 代码支持编译器转换成二进制代码同时也支持片上解析运行,非常高效灵活。因此可适合非常多的场景。如对于嵌入式平台这种低代码存储的设备,使用编译器转换成二进制代码则更加合适,而对于平板、手表这种设备,则可以用运行时文件解析的方式运行,则可以轻松定制丰富的 App 应用。Slint 语言设计了优秀的接口定义语法,强制将用户界面和后台业务逻辑分离,因此使得团队各方面人员能够专注于各自业务,同时提供高效的合作效率。

GUI 开发流程

Slint 框架开发GUI 界面使用以下流程:

  • 构建共享控件或自定义控件
  • 使用 Slint 文本语言描述界面的树形节点
  • 设置各节点的外观、文本内容,位置大小依赖等
  • 绑定属性的值到相应的计算表达式,根据依赖的属性自动计算目标属性的值和内容
  • 绑定动画触发条件和定义动画效果
  • 定义数据结构和模型,通过接口让后台或其他 GUI 模块访问和修改
  • 开发后台处理逻辑,实现公共接口的处理逻辑

Slint 代码示例

GUI(部分)

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT

import { DemoPalette, Page } from "common.slint";
import { HomePage } from "./home_page.slint";
import { InkLevel, InkPage } from "./ink_page.slint";
import { SettingsPage, PrinterSettings } from "./settings_page.slint";
import { PrinterQueue } from "./printer_queue.slint";

// re-export for the native code
export { PrinterQueue, PrinterSettings }

import "./fonts/NotoSans-Regular.ttf";
import "./fonts/NotoSans-Bold.ttf";

component SideBarIcon inherits Rectangle {
    in-out property <bool> active;

    callback activate;

    GridLayout {
        padding: 0px;
        @children
    }

    TouchArea {
        clicked => { root.activate(); }
    }
}

component MainWindow inherits Window {
    /// Note that this property is overwritten in the .cpp and .rs code.
    /// The data is only in this file so it looks good in the viewer
    in property <[InkLevel]> ink-levels: [
        {color: #0ff, level: 60%},
        {color: #ff0, level: 80%},
        {color: #f0f, level: 70%},
        {color: #000, level: 30%},
    ];
    out property <int> active-page: 0;

    callback quit();

    width: 772px;
    height: 504px;
    title: @tr("Slint printer demo");
    background: DemoPalette.main-background;
    default-font-family: "Noto Sans";
    default-font-size: DemoPalette.base-font-size;

    HorizontalLayout {
        padding: 10px;
        padding-left: 67px;

        main-view := Rectangle {
            height: 100%;
            border-radius: 30px;
            background: DemoPalette.page-background-color;

            Rectangle {
                clip: true;
                x: main-view.border-radius / 2;
                y: main-view.border-radius / 2;
                width: main-view.width - main-view.border-radius;
                height: main-view.height - main-view.border-radius;

                home-page := HomePage {
                    y: root.active-page == 0 ? 0 : root.active-page < 0 ? - self.height - 1px : parent.height + 1px;
                    animate y { duration: 125ms; easing: ease; }
                }

                SettingsPage {
                    y: root.active-page == 1 ? 0 : root.active-page < 1 ? - self.height - 1px : parent.height + 1px;
                    animate y { duration: 125ms; easing: ease; }
                }

                InkPage {
                    y: root.active-page == 2 ? 0 : root.active-page < 2 ? - self.height - 1px : parent.height + 1px;
                    ink-levels <=> root.ink-levels;
                    page-visible: root.active-page == 2;
                    animate y { duration: 125ms; easing: ease; }
                }
            }
        }
    }

    sidebar := Rectangle {
        function icon-y(index: int) -> length {
            return 100px // top padding
                + index * 72px;
        }

        width: 57px;
        x: 10px;


        Image {
            x:0;
            source: @image-url("images/page_selection.svg");
            y: sidebar.icon-y(root.active-page) - self.width / 2;
            width: main-view.x - sidebar.x + 1px;
            height: 1.75 * self.width;
            colorize: DemoPalette.page-background-color;
            animate y {
                duration: 125ms;
            }
        }

        for page-icon[idx] in [
            @image-url("images/home.svg"),
            @image-url("images/settings.svg"),
            @image-url("images/ink.svg"),
        ] : SideBarIcon {
            activate => {
                root.active-page = idx;
            }

            y: sidebar.icon-y(idx);
            x: 16px;
            height: 35px;
            width: 30px;

            icon := Image {
                colorize: (root.active-page == idx) ? DemoPalette.active-page-icon-color : DemoPalette.inactive-page-icon-color;
                animate colorize {
                    duration: 125ms;
                }
                source: page-icon;
                image-fit: contain;
                width: 100%;
                height: 100%;
            }
        }

        Rectangle {
            y: sidebar.icon-y(3) + 17px;
            x: 12px;
            background: #6284FF;
            height: 2px;
            width: 37px;
        }

        SideBarIcon {
            activate => {
                DemoPalette.night-mode = !DemoPalette.night-mode;
            }

            y: sidebar.icon-y(4);
            x: 16px;
            height: 35px;
            width: 30px;

            Image {
                colorize: DemoPalette.night-mode ? #F1FF98 : DemoPalette.inactive-page-icon-color;
                source: DemoPalette.night-mode ? @image-url("images/moon_full.svg") : @image-url("images/moon.svg");
                image-fit: contain;
                width: 100%;
                height: 100%;
            }
        }
    }
}

后台 Rust

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT

#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;

slint::include_modules!();

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
pub fn main() {
    // This provides better error messages in debug mode.
    // It's disabled in release mode so it doesn't bloat up the file size.
    #[cfg(all(debug_assertions, target_arch = "wasm32"))]
    console_error_panic_hook::set_once();

    let main_window = MainWindow::new().unwrap();
    main_window.set_ink_levels(slint::VecModel::from_slice(&[
        InkLevel { color: slint::Color::from_rgb_u8(0, 255, 255), level: 0.40 },
        InkLevel { color: slint::Color::from_rgb_u8(255, 0, 255), level: 0.20 },
        InkLevel { color: slint::Color::from_rgb_u8(255, 255, 0), level: 0.50 },
        InkLevel { color: slint::Color::from_rgb_u8(0, 0, 0), level: 0.80 },
    ]));

    let main_weak = main_window.as_weak();
    main_window.on_fax_number_erase(move || {
        let main_window = main_weak.unwrap();
        let mut fax_number = main_window.get_fax_number().to_string();
        fax_number.pop();
        main_window.set_fax_number(fax_number.into());
    });

    let main_weak = main_window.as_weak();
    main_window.on_fax_send(move || {
        let main_window = main_weak.upgrade().unwrap();
        let fax_number = main_window.get_fax_number().to_string();
        println!("Sending a fax to {}", fax_number);
        main_window.set_fax_number(slint::SharedString::default());
    });

    main_window.on_quit(move || {
        #[cfg(not(target_arch = "wasm32"))]
        std::process::exit(0);
    });

    main_window.run().unwrap();
}

运行效果


原文作者:Rust嵌入式;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-11-13

  • 博文量
    64
  • 访问量
    45602