Rust语言有那些好的GUI库?

关注者
335
被浏览
1,820,632

24 个回答

说说截至2022.2月的调研和体验

更新一下,根据最近的调研

这里只提Native原生UI库,web技术混合的UI开发不涉及。如果你的程序需要商业生产环境,以下是我的推荐心得。


1.gtk-rs(首选推荐) 大名鼎鼎的GTK,撑起了Linux的UI大旗 License:LGPL

使用gtk的还有一个好处,用户规模巨大,相对fltk的小众来说,更加保险。虽说gtk是在linux和gnome打天下的,但windows下仍然存在大量的gtk移植程序。

gtk是用c写的库,用c写的东西很方便给其它语言绑定,rust也不例外,绑定不复杂。gtk3的mingw64部署并不复杂,但msvc上部署把我折腾坏了。然后最近因为要用cairo库写点东西,又搞了一下gtk4,发现打开了新天地。

因为gtk的*nix下部署非常简单,我就不说了,着重说一下windows下msvc工具集的部署。

gtk4官方的一个目标是简化windows下的编译和部署,除了gnu工具链(mingw64)之外,增强对msvc的支持,我试用了一下,很简单。下面只讲msvc的编译方法。这样可以更加灵活和win32工具库集成了。

1)官方推荐的方法(不推荐,因为最新代码原因,很可能编译不过,除非你一个一个选tag)

GUI development with Rust and GTK 4

2)vcpkg(推荐)

为什么推荐?因为微软把能编译的东西测试好了,自动帮你下载工具链,编译好,非常贴心。

下面的教程我只在msvc2019测试过

安装package-confg工具,并将bin目录加入PATH

pkg-config-lite

如果你的rust环境是gnu的,务必切换回msvc

rustup default stable-msvc

直接在vcpkg上安装gtk(最新的vcpkg默认就是gtk4)

vcpkg install gtk --triplet x64-windows

安装好后,只需要设置两个环境变量

(下文的%VCPKGDIR%是你vcpkg的安装目录,不要无脑照猫画虎)

SET PKG_CONFIG_PATH %VCPKGDIR%\installed\x64-windows\lib\pkgconfig
SET GTK_LIB_DIR %VCPKGDIR%\installed\x64-windows\lib

你需要将vcpkg装好的gtk4库的dll暴露到搜索路径中,加入环境变量PATH中

SET PATH=%VCPKGDIR%\installed\x64-windows\bin;%PATH%

然后编写一个Cargo.toml

[dependencies]
gtk = { version = "0", package = "gtk4" }

就可以用gtk-rs飞了

生成的文件不大,release模式编译完,加上dll依赖,用7z压缩完只有不到6Mb,也算是小巧了。

2.FLTK-rs(首选推荐)

优势:
这个库以及rust绑定非常成熟,可以用于生产
跨平台部署非常容易,生成目标文件很小,大部分示例不到1MB
控件众多,还可方便和OpenGL以及包装库结合,如glow,glut,glium,wgpu等,开发高性能程序
License友好,是一个修改过的LGPL,但作者允许用于闭源静态链接,完全可以商业闭源使用。
c++之父推荐

不足:
库的理念略老,用了react和vue之后,发现这种老式开发过程还是略显麻烦
默认的主题也很老,不够现代美观。不过对于大公司来说,这也不是问题,找美术订制一套主题即可。
有一个webview集成,目前是可用状态,期待以后成熟
github.com/fltk-rs/fltk

3.Native Windows GUI(推荐)

如果是写windows ui,不考虑跨平台的话,还是可以用于生产的

优势:
成熟,因为是对win32 api的包装
License,MIT

不足:
不能跨平台

4.qt(一般推荐吧)
存在多个qt的绑定
License:LGPL


优势:
qt的优势,成熟

不足:
qt用c++而非c语言编写,诞生之时,理念先进,魔改了很多c++没有的东西,所以rust绑定,部署和开发非常麻烦,尤其是windows环境,想试的同学可以参考
rustcc.cn/article?


5.其他,druid,iced,orbtk,egui(目前不推荐)
这些虽然很新,别的答主也说过,我就不详说了,
这些库还在开发中,欢迎大家贡献力量。希望这里能出一匹黑马,
但,强烈不建议用于生产环境。

建议关注:slint-ui.com/

slint-ui 是rust基金会银级会员,同时与几家嵌入式相关的平台厂商有合作关系。开发之初就原生支持多种语言,主要支持rust/c++/NodeJs。

另专写了一篇文章做了更详细的介绍:Slint ui介绍

开发人员来自QT;界面开发语言类似qt的qml;开发方式类似QT的qml+cpp, 采用slint+cpp/slint+rust方式;官网有运行在stm32上的视频,以及以wasm方式运行在浏览器上的在线体验demo。slint与qml不同的是,slint最终是全部转换成了本地语言代码,而qml到目前为止,也只能做到一小部分转换成cpp代码。

基本控件完备,目前版本0.3.4(2023.02),下一版本1.0正式版。版本正在快速迭代。但缺点是控制细粒度赶QT还有较大差距。

slint rust:文档:slint-ui.com/releases/0

slint c++文档:slint-ui.com/releases/0

建议rust/cpp文档对比着看,个人感觉,c++文档更易懂一些,可能与本人更熟悉cpp有关。

当前已经支持的控件(下面图片引用自cpp的文档页面)

slint架构:

举例:main.slint:

import {    
    GroupBox, LineEdit, Button, 
    Slider, SpinBox,
    StandardTableView    
} from "std-widgets.slint";

MainWindow := Window{
    title: "Main Window";
    width: 600px;
    height: 500px;
    VerticalLayout { 
        // line comment
        /* this is a 
            /* single */ 
            comment 
        */
        spacing: 5px;
        padding-left: 25px;
        padding-right: 25px;
        alignment: center;
        Button {
            text: "Click Me";
            clicked => { self.text = "Clicked"; }
        }
        Text { 
            height: 50px;
            font-size: 27px;
            font-weight: 700;
            color: #6776FF;  
            text: "line text";
         }
        HorizontalLayout {  
            width: parent.width;
            height: 25px;  
            alignment: center; 
            spacing: 5px;   
            
            Rectangle { 
                width: 24px;
                height: 24px;
                border-radius: width / 2;
                background: red;
                
                Rectangle { 
                    width: 12px;
                    height: 12px;
                    border-radius: width / 2;
                    background: white;
                    x: parent.width/4;
                    y: parent.height/4;
                    
                }
             }         
            Slider {
                //width: parent.width * 3 / 8;
                height: parent.height;
                value: 42;
            }
            SpinBox {
                //width: parent.width * 3 / 8;
                height: parent.height;
                value: 42;
            }
        }
        GroupBox{
            title:"Group Box";
            height: 100px;            
            LineEdit {
                placeholder-text: "enter text";
            }
        }
        
        Rectangle  {
            width: parent.width * 3 / 4;
            height: 202px;
            border-color: #86e086;
            border-width: 1px;
            StandardTableView {
                width: parent.width;
                height: 200px;
                columns: [
                    { title: "colum 1" },
                    { title: "colum 2" },
                ];
                rows: [
                    [{ text: "item 11" }, { text: "item 12" },],
                    [{ text: "item 21" }, { text: "item 22" },],
                    [{ text: "item 31" }, { text: "item 32" },]
                ];
            }
        }  
        
        HorizontalLayout {
            spacing: 5px;
            height: 30px;
            Rectangle { background: red; width: 20px; }
            Rectangle { background: blue; min-width: 10px; }
            Rectangle { background: yellow; horizontal-stretch: 1; }
            Rectangle { background: green; horizontal-stretch: 2; }
        }
    }
}

main.rs

slint::include_modules!();

fn main() {
    MainWindow::new().run();
}

build.rs

fn main() {
    slint_build::compile("ui/main.slint").unwrap();
}

cargo.toml

[package]
name = "mytest"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
slint = "0.3.4"
[build-dependencies]
slint-build = "0.3.4"

执行命令:cargo run,运行效果如下图,以上所有程序开发均在vs code下完成(依赖slint官方插件)


rust还不怎么会,slint怎么与rust/c++交互还没有研究

slint这种写界面的方式谁不喜欢呢。最重要的是,界面最终转换成了rust/cpp,而不是简单的脚本解释运行,也没用到v8之类的浏览器、虚拟机技术。

slint-ui是嵌入式开发的福音,抛开rust不说,由于支持cpp,从此再也不用忍受lvgl/minigui之类各种各样的一大票用c搞出来的杂七杂八蹩脚又折磨人的UI框架(c框架心智负担太重,且很少也很难做到界面与逻辑分离,一旦需求变动几乎是灾难)。也许有人会说既然用cpp了为什么不用QT, QT太庞大,不适合没有操作系统的单片机。那为什么不用QT for mcu呢?qt for mcu 我没用过,但它是商业软件不开源,slint-ui支持GPLv3许可证。

MCU支持:

当前版本下mcu相关API只在rust中可用,以后会开发c++版本的api,官方是这样说的:

These new platform abstraction and rendering APIs are only available for the Rust programming language today; C++ is in our future plans

关于移植到MCU相关的信息可以看一下官方文章及项目例程:

slint::docs::mcu - Rust

Porting the Slint UI Toolkit to a Microcontroller with 264K RAM — Slint Blog

slint-mcu-rust-template.git

stm32芯片-有DMAhttps://www.zhihu.com/video/1604897879910490113RP2040-264K RAM/2M flash 无DMAhttps://www.zhihu.com/video/1604899002016800768