.. | ||
include | ||
LICENSES | ||
src | ||
CMakeLists.txt | ||
idf_component.yml | ||
LICENSE | ||
README.md |
Slint
Slint is a declarative GUI toolkit to build native user interfaces for desktop and embedded applications written in Rust, C++, or JavaScript.
This component provides the C++ version of Slint for the Espressif IoT Development Framework.
It has been tested on ESP32-S3 devices.
Getting Started
Prerequisites
- Install the Espressif IoT Development Framework and open a terminal or command prompt with the environment set up. On Windows, follow the Using the Command Prompt instructions, on macOS and Linux, follow the Set up the Environment Variables instructions.
- Make sure that you have Rust installed.
- Install the Rust toolchains for Espressif SoCs with Xtensa and RISC-V targets.
Hello World
The following steps will guide from the a bare-bones esp-idf "hello_world" to a GUI with Slint.
- Start by creating a new project:
idf.py create-project slint-hello-world
cd slint-hello-world
- Select your chipset with
idf.py set-target
, for example if you're using anESP32S3
chipset, run
idf.py set-target esp32s3
- Add a Board Support Package that matches your device as a dependency. For example, if you're using an ESP-BOX, run
idf.py add-dependency esp-box
- Add Slint as a dependency:
idf.py add-dependency slint/slint
- Ensure that Espressif's Rust toolchain is selected for building. Either set the
RUSTUP_TOOLCHAIN
environment variable to the valueesp
or create a file calledrust-toolchain.toml
in your project directory with the following contents:
[toolchain]
channel = "esp"
- Remove
main/slint-hello-world.c
. - Create a new file
main/slint-hello-world.cpp
with the following contents:
#include <stdio.h>
#include <esp_err.h>
#include <bsp/display.h>
#include <bsp/esp-bsp.h>
#include <slint-esp.h>
#if defined(BSP_LCD_DRAW_BUFF_SIZE)
# define DRAW_BUF_SIZE BSP_LCD_DRAW_BUFF_SIZE
#else
# define DRAW_BUF_SIZE (BSP_LCD_H_RES * CONFIG_BSP_LCD_DRAW_BUF_HEIGHT)
#endif
#include "appwindow.h"
extern "C" void app_main(void)
{
/* Initialize display */
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_handle_t panel_handle = NULL;
const bsp_display_config_t bsp_disp_cfg = {
.max_transfer_sz = DRAW_BUF_SIZE * sizeof(uint16_t),
};
bsp_display_new(&bsp_disp_cfg, &panel_handle, &io_handle);
/* Set display brightness to 100% */
bsp_display_backlight_on();
std::optional<esp_lcd_touch_handle_t> touch_handle;
/* Allocate a drawing buffer */
static std::vector<slint::platform::Rgb565Pixel> buffer(BSP_LCD_H_RES * BSP_LCD_V_RES);
/* Initialize Slint's ESP platform support*/
slint_esp_init(slint::PhysicalSize({ BSP_LCD_H_RES, BSP_LCD_V_RES }), panel_handle,
touch_handle, buffer);
/* Instantiate the UI */
auto ui = AppWindow::create();
/* Show it on the screen and run the event loop */
ui->run();
}
- Create
main/appwindow.slint
with the following contents:
import { VerticalBox, AboutSlint } from "std-widgets.slint";
export component AppWindow {
VerticalBox {
AboutSlint {}
Text {
text: "Hello World";
font-size: 18px;
horizontal-alignment: center;
}
}
}
- Edit
main/CMakeLists.txt
to adjust for the newslint-hello-world.cpp
, addslint
as required component, and instruction the build system to compileappwindow.slint
toappwindow.h
. The file should look like this:
idf_component_register(SRCS "slint-hello-world.cpp" INCLUDE_DIRS "." REQUIRES slint)
slint_target_sources(${COMPONENT_LIB} appwindow.slint)
-
Open the configuration editor with
idf.py menuconfig
:- Change the stack size under
Component config --> ESP System Settings --> Main task stack size
to at least8192
. You may need to tweak this value in the future if you run into stack overflows. - You may need additional device-specific settings. For example if your device has external SPI RAM, you may need to enable that. For details for ESP32-S3 based devices see how to Configure the PSRAM.
- Quit the editor with
Q
and save the configuration.
Alternatively, check in a default sdkconfig tweaked from your board that adds the right amount of ram, flash, and use
CONFIG_MAIN_TASK_STACK_SIZE=8192
- Change the stack size under
-
Build the project with
idf.py build
. -
Connect your device, then flash and run it with
idf.py flash monitor
. -
Observe Slint rendering "Hello World" on the screen 🎉.
Congratulations, you're all set up to develop with Slint. For more information, check out our online documentation.
If you have feedback or questions, feel free to reach out to the Slint community:
- Chat with us on Mattermost.
- Ask questions on GitHub
- Contact us on Twitter or Mastodon
- Report a bug on Github
Troubleshooting
You may run into compile or run-time issues due to Slint's requirements. The following sections track issues we're aware of and how to solve them.
Rust Compilation Error During Slint Build
You see the following error:
error: the `-Z` flag is only accepted on the nightly channel of Cargo, but this is the `stable` channel
Solution: You need to configure your Rust toolchain to use the esp channel. Either set the RUSTUP_TOOLCHAIN
environment variable to the value esp
or create a file called rust-toolchain.toml
in your project directory with the following contents:
[toolchain]
channel = "esp"
Error compiling Slint for ESP-IDF on Windows
You see errors about slint-compiler
:
Error copying file (if different) from "C:/path/build/./cargo/build/x86_64-pc-windows-msvc/release/slint-compiler" to "C:/path/build/_deps/slint-build".
Solution: At the moment development development on Windows while targeting ESP-IDF is not supported. We're working on a fix and in the meantime we recommend using Windows Subsystem for Linux.
The device crashes at boot or enter a boot loop
One reason could be that you don't have enough ram for the heap or the stack. Make sure that the stack is big enough (~8KiB), and that all the RAM was made available for the heap allocator.
License
You can use Slint under any of the following licenses, at your choice:
See also the Licensing FAQ.
Slint is also available with a third license (Royalty Free) for desktop applications.