Expand description
Slint
This crate is the main entry point for embedding user interfaces designed with Slint in Rust programs. If you are new to Slint, start with the Walk-through tutorial If you are already familiar with Slint, the following topics provide related information.
Related topics
How to use this crate:
Designs of user interfaces are described in the .slint
design markup language. There are three ways
of including them in Rust:
- The
.slint
code is inline in a macro. - The
.slint
code in external files compiled withbuild.rs
- The
.slint
code is loaded dynamically at run-time from the file system, by using the interpreter API.
With the first two methods, the markup code is translated to Rust code and each component is turned into a Rust struct with functions. Use these functions to instantiate and show the component, and to access declared properties. Check out our sample component for more information about the generation functions and how to use them.
The .slint code in a macro
This method combines your Rust code with the .slint
design markup in one file, using a macro:
slint::slint!{
export component HelloWorld {
Text {
text: "hello world";
color: green;
}
}
}
fn main() {
HelloWorld::new().unwrap().run().unwrap();
}
The .slint code in external files is compiled with build.rs
When your design becomes bigger in terms of markup code, you may want move it to a dedicated
.slint
file. It’s also possible to split a .slint
file into multiple files using modules.
Use a build script to compile
your main .slint
file:
In your Cargo.toml add a build
assignment and use the slint-build
crate in build-dependencies
:
[package]
...
build = "build.rs"
edition = "2021"
[dependencies]
slint = "1.1.0"
...
[build-dependencies]
slint-build = "1.1.0"
Use the API of the slint-build crate in the build.rs
file:
fn main() {
slint_build::compile("ui/hello.slint").unwrap();
}
Finally, use the include_modules!
macro in your main.rs
:
slint::include_modules!();
fn main() {
HelloWorld::new().unwrap().run().unwrap();
}
The cargo-generate tool is a great tool to up and running quickly with a new Rust project. You can use it in combination with our Template Repository to create a skeleton file hierarchy that uses this method:
cargo install cargo-generate
cargo generate --git https://github.com/slint-ui/slint-rust-template
Generated components
Currently, only the last component in a .slint
source file is mapped to a Rust structure that be instantiated. We are tracking the
resolution of this limitation in https://github.com/slint-ui/slint/issues/784.
The component is generated and re-exported to the location of the include_modules!
or slint!
macro. It is represented
as a struct with the same name as the component.
For example, if you have
export component MyComponent inherits Window { /*...*/ }
in the .slint file, it will create a
struct MyComponent{ /*...*/ }
See also our sample component for more information about the API of the generated struct.
A component is instantiated using the fn new() -> Self
function. The following
convenience functions are available through the ComponentHandle
implementation:
fn clone_strong(&self) -> Self
: creates a strongly referenced clone of the component instance.fn as_weak(&self) -> Weak
: to create a weak reference to the component instance.fn show(&self)
: to show the window of the component.fn hide(&self)
: to hide the window of the component.fn run(&self)
: a convenience function that first callsshow()
, followed by spinning the event loop, andhide()
when returning from the event loop.fn global<T: Global<Self>>(&self) -> T
: an accessor to the global singletons,
For each top-level property
- A setter
fn set_<property_name>(&self, value: <PropertyType>)
- A getter
fn get_<property_name>(&self) -> <PropertyType>
For each top-level callback
fn invoke_<callback_name>(&self)
: to invoke the callbackfn on_<callback_name>(&self, callback: impl Fn(<CallbackArgs>) + 'static)
: to set the callback handler.
Note: All dashes (-
) are replaced by underscores (_
) in names of types or functions.
After instantiating the component, call ComponentHandle::run()
on show it on the screen and spin the event loop to
react to input events. To show multiple components simultaneously, call ComponentHandle::show()
on each instance.
Call run_event_loop()
when you’re ready to enter the event loop.
The generated component struct acts as a handle holding a strong reference (similar to an Rc
). The Clone
trait is
not implemented. Instead you need to make explicit ComponentHandle::clone_strong
and ComponentHandle::as_weak
calls. A strong reference should not be captured by the closures given to a callback, as this would produce a reference
loop and leak the component. Instead, the callback function should capture a weak component.
Threading and Event-loop
For platform-specific reasons, the event loop must run in the main thread, in most backends, and all the components must be created in the same thread as the thread the event loop is running or is going to run.
You should perform the minimum amount of work in the main thread and delegate the actual logic to another
thread to avoid blocking animations. Use the invoke_from_event_loop
function to communicate from your worker thread to the UI thread.
To run a function with a delay or with an interval use a Timer
.
Type Mappings
The types used for properties in .slint
design markup each translate to specific types in Rust.
The follow table summarizes the entire mapping:
.slint Type | Rust Type | Note |
---|---|---|
int | i32 | |
float | f32 | |
bool | bool | |
string | SharedString | A reference-counted string type that can be easily converted to a str reference. |
color | Color | |
brush | Brush | |
image | Image | |
physical_length | f32 | The unit are physical pixels. |
length | f32 | At run-time, logical lengths are automatically translated to physical pixels using the device pixel ratio. |
duration | i64 | At run-time, durations are always represented as signed 64-bit integers with millisecond precision. |
angle | f32 | The value in degrees |
relative-font-size | f32 | Relative font size factor that is multiplied with the Window.default-font-size and can be converted to a length . |
structure | struct of the same name | |
anonymous object | anonymous tuple | The fields are in alphabetical order. |
enumeration | enum of the same name | The values are converted to CamelCase |
array | ModelRc | Arrays are represented as models, so that their contents can change dynamically. |
Point | LogicalPosition | A struct with x and y fields, representing logical coordinates. |
For user defined structures in the .slint, an extra struct is generated.
For example, if the .slint
contains
export struct MyStruct {
foo: int,
bar: string,
names: [string],
}
The following struct would be generated:
#[derive(Default, Clone, Debug, PartialEq)]
struct MyStruct {
foo : i32,
bar: slint::SharedString,
names: slint::ModelRc<slint::SharedString>,
}
The .slint
file allows you to utilize Rust attributes and features for defining structures using the @rust-attr()
directive.
This enables you to customize the generated code by applying additional traits, derivations, or annotations.
Consider the following structure defined in the .slint
file with Rust attributes:
@rust-attr(derive(serde::Serialize, serde::Deserialize))
struct MyStruct {
foo : i32,
}
Based on this structure, the following Rust code would be generated:
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(Default, Clone, Debug, PartialEq)]
struct MyStruct {
foo : i32,
}
Exported Global singletons
When you export a global singleton from the main file, it is also generated with the exported name. Like the main component, the generated struct have inherent method to access the properties and callback:
For each property
- A setter:
fn set_<property_name>(&self, value: <PropertyType>)
- A getter:
fn get_<property_name>(&self) -> <PropertyType>
For each callback
fn invoke_<callback_name>(&self, <CallbackArgs>) -> <ReturnValue>
to invoke the callbackfn on_<callback_name>(&self, callback: impl Fn(<CallbackArgs>) + 'static)
to set the callback handler.
The global can be accessed with the ComponentHandle::global()
function, or with Global::get()
See the documentation of the Global
trait for an example.
Feature flags
-
compat-1-0
(enabled by default) — Mandatory feature: This feature is required to keep the compatibility with Slint 1.0 Newer patch version may put current functionality behind a new feature that would be enabled by default only if this feature was added. More info in this blog post -
std
(enabled by default) — Enable use of the Rust standard library. -
gettext
— Enable the translations using gettextthe
@tr(...)
code from .slint files will be transformed into call todgettext
with the crate name as domain nametranslations must be enabled with the
init_translations!
macro -
libm
— This feature enables floating point arithmetic emulation using the libm crate. Use this in MCU environments where the processor does not support floating point arithmetic. -
log
— If enabled, calls ofdebug()
in.slint
files use to thelog::debug!()
macro of the log crate instead of justprintln!()
. -
software-renderer-systemfonts
— This feature enables the software renderer to pick up fonts from the operating system for text rendering. -
unsafe-single-threaded
— Slint uses internally somethread_local
state.When the
std
feature is enabled, Slint can usestd::thread_local!
, but when in a#![no_std]
environment, we need a replacement. Using this feature, Slint will just use static variable disregarding Rust’s Send and Sync safetySafety : You must ensure that there is only one single thread that call into the Slint API
-
accessibility
(enabled by default) — Enable integration with operating system provided accessibility APIsEnabling this feature will try to expose the tree of UI elements to OS provided accessibility APIs to support screen readers and other assistive technologies.
Backends
Slint needs a backend that will act as liaison between Slint and the OS.
By default, Slint will use the Qt backend, if Qt is installed, otherwise, it
will use Winit with Femtovg.
Both backends are compiled in. If you want to not compile one of these you need
to disable the default feature and re-enable one backend. It is also possible
to use Slint without backend if you provide the platform abstraction yourself
with platform::set_platform()
.
If you enable the Winit backend, you need to also include a renderer.
renderer-winit-femtovg
is the only stable renderer, the other ones are experimental
It is also possible to select the backend and renderer at runtime when several
are enabled, using the SLINT_BACKEND
environment variable.
SLINT_BACKEND=Qt
selects the Qt backendSLINT_BACKEND=winit
selects the winit backendSLINT_BACKEND=winit-femtovg
selects the winit backend with the femtovg rendererSLINT_BACKEND=winit-skia
selects the winit backend with the skia rendererSLINT_BACKEND=winit-software
selects the winit backend with the software renderer
If the selected backend is not available, the default will be used.
Here are the cargo features controlling the backend:
-
backend-qt
(enabled by default) — The Qt backend feature uses Qt for the windowing system integration and rendering. This backend also provides thenative
style. It requires Qt 5.15 or later to be installed. If Qt is not installed, the backend will not be operational -
backend-winit
(enabled by default) — The winit crate is used for the event loop and windowing system integration. It supports Windows, macOS, web browsers, X11 and Wayland. X11 and wayland are only available when compiling for Linux or other Unix-like operating systems. With this feature, both X11 and Wayland are supported. For a smaller build, omit this feature and select one of the other specificbackend-winit-XX
features. -
backend-winit-x11
— Simliar tobackend-winit
this enables the winit based event loop but only with support for the X Window System on Unix. -
backend-winit-wayland
— Simliar tobackend-winit
this enables the winit based event loop but only with support for the Wayland window system on Unix. -
renderer-winit-femtovg
(enabled by default) — Make the winit backend capable of rendering using the femtovg crate. Must be used in combination withbackend-winit
,backend-winit-x11
, orbackend-winit-wayland
. -
renderer-winit-skia
— Make the winit backend capable of rendering using Skia. Must be used in combination withbackend-winit
,backend-winit-x11
, orbackend-winit-wayland
. -
renderer-winit-skia-opengl
— Same asrenderer-winit-skia
, but Skia will always use OpenGL. -
renderer-winit-skia-vulkan
— Same asrenderer-winit-skia
, but Skia will always use Vulkan. -
renderer-winit-software
— Make the winit backend capable of rendering using the software renderer. Must be used in combination withbackend-winit
,backend-winit-x11
, orbackend-winit-wayland
.
Modules
- This is a pseudo module which only exist for documentation purposes as a way to show the Slint documentation as part of rustdoc.
- This module contains items that you need to use or implement if you want use Slint in an environment without one of the supplied platform backends such as qt or winit.
Macros
- This macro is the same as
std::format!
, but it returns aSharedString
instead. - Include the code generated with the slint-build crate from the build script. After calling
slint_build::compile
in yourbuild.rs
build script, the use of this macro includes the generated Rust code and makes the exported types available for you to instantiate. - Initialize translations when using the
gettext
feature. - This macro allows you to use the Slint design markup language inline in Rust code. Within the braces of the macro you can use place Slint code and the named exported components will be available for instantiation.
Structs
- Color represents a color in the Slint run-time, represented using 8-bit channels for red, green, blue and the alpha (opacity). It can be conveniently converted using the
to_
andfrom_
(a)rgb helper functions: - Provides a filtered subset of rows by another
Model
. - An image type that can be displayed by the Image element. You can construct Image objects from a path to an image file on disk, using
Self::load_from_path
. - The return value of the
spawn_local()
function - Error generated if an image cannot be loaded for any reasons.
- A position represented in the coordinate space of logical pixels. That is the space before applying a display device specific scale factor.
- A size represented in the coordinate space of logical pixels. That is the space before applying a display device specific scale factor.
- Provides rows that are generated by a map function based on the rows of another Model
- Represent a handle to a view that listens to changes to a model.
- ModelRc is a type wrapper for a reference counted implementation of the
Model
trait. - A position represented in the coordinate space of physical device pixels. That is the space after applying a display device specific scale factor to pixels from the logical coordinate space.
- A size represented in the coordinate space of physical device pixels. That is the space after applying a display device specific scale factor to pixels from the logical coordinate space.
- RgbaColor stores the red, green, blue and alpha components of a color with the precision of the generic parameter T. For example if T is f32, the values are normalized between 0 and 1. If T is u8, they values range is 0 to 255. This is merely a helper class for use with
Color
. - SharedPixelBuffer is a container for storing image data as pixels. It is internally reference counted and cheap to clone.
- A string type used by the Slint run-time.
- SharedVector holds a reference-counted read-only copy of
[T]
. - Provides a sorted view of rows by another
Model
. - Represents an item in a StandardListView and a StandardTableView. This is the Rust/C++ type for the StandardListViewItem type in Slint files, when declaring for example a
property <[StandardListViewItem]> my-list-view-model;
. - Represent an TableColumn header
- Timer is a handle to the timer system that allows triggering a callback to be called after a specified period of time.
- A
Model
backed by aVec<T>
- Struct that’s used to hold weak references of a Slint component
- This type represents a window towards the windowing system, that’s used to render the scene of a component. It provides API to control windowing system specific aspects such as the position on the screen.
Enums
- A brush is a data structure that is used to describe how a shape, such as a rectangle, path or even text, shall be filled. A brush can also be applied to the outline of a shape, that means the fill of the outline itself.
- This enum describes whether a Window is allowed to be hidden when the user tries to close the window. It is the return type of the callback provided to Window::on_close_requested.
- Error returned from the
invoke_from_event_loop()
andquit_event_loop()
function - This enum describes a low-level access to specific graphics APIs used by the renderer.
- The platform encountered a fatal error.
- This enum describes the different rendering states, that will be provided to the parameter of the callback for
set_rendering_notifier
on theslint::Window
. - This enum describes the different error scenarios that may occur when the application registers a rendering notifier on a
slint::Window
. - The TimerMode specifies what should happen after the timer fired.
- The position of the window in either physical or logical pixels. This is used with
Window::set_position
. - The size of a window represented in either physical or logical pixels. This is used with
Window::set_size
.
Traits
- This trait describes the common public API of a strongly referenced Slint component. It allows creating strongly-referenced clones, a conversion into/ a weak pointer as well as other convenience functions.
- This trait is used to obtain references to global singletons exported in
.slint
markup. Alternatively, you can useComponentHandle::global
to obtain access. - A Model is providing Data for the repeated elements with
for
in the.slint
language - Extension trait with extra methods implemented on types that implement
Model
- This trait defines the interface that users of a model can use to track changes to a model. It is supplied via
Model::model_tracker
and implementation usually return a reference to its field ofModelNotify
. - Internal trait that’s used to map rendering state callbacks to either a Rust-API provided impl FnMut or a struct that invokes a C callback and implements Drop to release the closure on the C++ side.
Functions
- Adds the specified function to an internal queue, notifies the event loop to wake up. Once woken up, any queued up functors will be invoked.
- Schedules the main event loop for termination. This function is meant to be called from callbacks triggered by the UI. After calling the function, it will return immediately and once control is passed back to the event loop, the initial call to
slint::run_event_loop()
will return. - Enters the main event loop. This is necessary in order to receive events from the windowing system in order to render to the screen and react to user input.
- Spawn a Future to run in the Slint event loop
Type Definitions
- Convenience alias for a pixel with three color channels (red, green and blue), each encoded as u8.
- Convenience alias for a pixel with four color channels (red, green, blue and alpha), each encoded as u8.