slint

Slint-python (Beta)

Slint is a UI toolkit that supports different programming languages. Slint-python is the integration with Python.

Warning Slint-python is in a beta phase of development: The APIs while mostly stable, may be subject to further changes. Any changes will be documented in the ChangeLog.

You can track the progress for the Python integration by looking at python-labelled issues at https://github.com/slint-ui/slint/labels/a%3Alanguage-python .

Slint Language Manual

The Slint Language Documentation covers the Slint UI description language in detail.

Prerequisites

Installation

Install Slint with uv or pip from the Python Package Index:

uv add slint

The installation uses binaries provided for macOS, Windows, and Linux for various architectures. If your target platform is not covered by binaries, uv will automatically build Slint from source. If that happens, you will then need some software development tools on your machine, as well as Rust.

Quick Start

  1. Create a new project with uv init.
  2. Add the Slint Python package to your Python project: uv add slint
  3. Create a file called app-window.slint:
import { Button, VerticalBox } from "std-widgets.slint";

export component AppWindow inherits Window {
    in-out property<int> counter: 42;
    callback request-increase-value();
    VerticalBox {
        Text {
            text: "Counter: \{root.counter}";
        }
        Button {
            text: "Increase value";
            clicked => {
                root.request-increase-value();
            }
        }
    }
}
  1. Create a file called main.py:
import slint

# slint.loader will look in `sys.path` for `app-window.slint`.
class App(slint.loader.app_window.AppWindow):
    @slint.callback
    def request_increase_value(self):
        self.counter = self.counter + 1

app = App()
app.run()
  1. Run it with uv run main.py

API Overview

Instantiating a Component

The following example shows how to instantiate a Slint component in Python:

app.slint

export component MainWindow inherits Window {
    callback clicked <=> i-touch-area.clicked;

    in property <int> counter;

    width: 400px;
    height: 200px;

    i-touch-area := TouchArea {}
}

The exported component is exposed as a Python class. To access this class, you have two options:

  1. Call slint.load_file("app.slint"). The returned object is a namespace, that provides the MainWindow class as well as any other explicitly exported component that inherits Window:

    import slint
    components = slint.load_file("app.slint")
    main_window = components.MainWindow()
    
  2. Use Slint's auto-loader, which lazily loads .slint files from sys.path:

    import slint
    # Look for for `app.slint` in `sys.path`:
    main_window = slint.loader.app.MainWindow()
    

    Any attribute lookup in slint.loader is searched for in sys.path. If a directory with the name exists, it is returned as a loader object, and subsequent attribute lookups follow the same logic.

    If the name matches a file with the .slint extension, it is automatically loaded with load_file and the namespace is returned.

    If the file name contains a dash, like app-window.slint, an attribute lookup for app_window tries to locate app_window.slint and then fall back to app-window.slint.

Accessing Properties

Properties declared as out or in-out in .slint files are visible as properties on the component instance.

main_window.counter = 42
print(main_window.counter)

Accessing Globals

Global Singletons are accessible in Python as properties in the component instance.

For example, this Slint code declares a PrinterJobQueue singleton:

export global PrinterJobQueue {
    in-out property <int> job-count;
}

Access it as a property on the component instance by its name:

print("job count:", instance.PrinterJobQueue.job_count)

Note: Global singletons are instantiated once per component. When declaring multiple components for export to Python, each instance has their own associated globals singletons.

Setting and Invoking Callbacks

Callbacks declared in .slint files are visible as callable properties on the component instance. Invoke them as functions to invoke the callback, and assign Python callables to set the callback handler.

In Slint, callbacks are defined using the callback keyword and can be connected to another component's callback using the <=> syntax.

my-component.slint

export component MyComponent inherits Window {
    callback clicked <=> i-touch-area.clicked;

    width: 400px;
    height: 200px;

    i-touch-area := TouchArea {}
}

The callbacks in Slint are exposed as properties and that can be called as functions.

main.py

import slint

component = slint.loader.my_component.MyComponent()
# connect to a callback

def clicked():
    print("hello")

component.clicked = clicked
// invoke a callback
component.clicked();

Another way to set callbacks is to sub-class and use the @slint.callback decorator:

import slint

class Component(slint.loader.my_component.MyComponent):
    @slint.callback
    def clicked(self):
        print("hello")

component = Component()

The @slint.callback() decorator accepts a name argument, if the name of the method does not match the name of the callback in the .slint file. Similarly, a global_name argument can be used to bind a method to a callback in a global singleton.

Type Mappings

Each type used for properties in the Slint Language translates to a specific type in Python. The following table summarizes the mapping:

.slint Type Python Type Notes
int int
float float
string str
color slint.Color
brush slint.Brush
image slint.Image
styled-text slint.StyledText
data-transfer slint.DataTransfer
length float
physical_length float
duration float The number of milliseconds
angle float The angle in degrees
structure dict/Struct When reading, structures are mapped to data classes, when writing dicts are also accepted.
array slint.Model

Arrays and Models

You can set array properties from Python by passing subclasses of slint.Model.

Use the slint.ListModel class to construct a model from an iterable:

component.model = slint.ListModel([1, 2, 3]);
component.model.append(4)
del component.model[0]

When sub-classing slint.Model, provide the following methods:

    def row_count(self):
        """Return the number of rows in your model"""

    def row_data(self, row):
        """Return data at specified row"""

    def set_row_data(self, row, data):
        """For read-write models, store data in the given row. When done call set.notify_row_changed:"
        ..."""
        self.notify_row_changed(row)

When adding or inserting rows, call notify_row_added(row, count) on the super class. Similarly, when removing rows, notify Slint by calling notify_row_removed(row, count).

Structs

Structs declared in Slint and exposed to Python via export are then accessible in the namespace that is returned when instantiating a component.

app.slint

export struct MyData {
    name: string,
    age: int
}

export component MainWindow inherits Window {
    in-out property <MyData> data;
}

main.py

The exported MyData struct can be constructed as follows:

import slint
# Look for for `app.slint` in `sys.path`:
main_window = slint.loader.app.MainWindow()

data = slint.loader.app.MyData(name = "Simon")
data.age = 10
main_window.data = data

Enums

Enums declared in Slint and exposed to Python via export are then accessible in the namespace that is returned when instantiating a component. The enums are subclasses of enum.Enum.

app.slint

export enum MyOption {
    Variant1,
    Variant2
}

export component MainWindow inherits Window {
    in-out property <MyOption> data;
}

main.py

Variants of the exported MyOption enum can be constructed as follows:

import slint
# Look for for `app.slint` in `sys.path`:
main_window = slint.loader.app.MainWindow()

value = slint.loader.app.MyOption.Variant2
main_window.data = value

Asynchronous I/O

Use Python's asyncio library to write concurrent Python code with the async/await syntax.

Slint's event loop is a full-featured asyncio event loop. While the event loop is running, asyncio.get_event_loop() returns a valid loop. To run an async function when starting the loop, pass a coroutine to slint.run_event_loop().

For the common use case of interacting with REST APIs, we recommend the aiohttp library.

Known Limitations

  • Pipes and sub-processes are only supported on Unix-like platforms.

Type Hints

PEP 484 introduces a standard syntax for type annotations to Python, enabling static analysis for type checking, refactoring, and code completion. Popular type checkers include mypy, Pyre, and Astral's ty.

Use Slint's slint-compiler to generate stub .py files for .slint files, which are annotated with type information. These replace the need to call load_file or any use of slint.loader.

  1. Create a new project with uv init.
  2. Add the Slint Python package to your Python project: uv add slint
  3. Create a file called app-window.slint:
import { Button, VerticalBox } from "std-widgets.slint";

export component AppWindow inherits Window {
    in-out property<int> counter: 42;
    callback request-increase-value();
    VerticalBox {
        Text {
            text: "Counter: \{root.counter}";
        }
        Button {
            text: "Increase value";
            clicked => {
                root.request-increase-value();
            }
        }
    }
}
  1. Run the slint-compiler to generate app_window.py: uvx slint-compiler -f python -o app_window.py app-window.slint

  2. Create a file called main.py:

import slint
import app_window

class App(app_window.AppWindow):
    @slint.callback
    def request_increase_value(self):
        self.counter = self.counter + 1

app = App()
app.run()
  1. Run it with uv run main.py

Third-Party Licenses

For a list of the third-party licenses of all dependencies, see the separate Third-Party Licenses page.

  1# Copyright © SixtyFPS GmbH <info@slint.dev>
  2# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
  3
  4r"""
  5.. include:: ../README.md
  6"""
  7
  8import os
  9import sys
 10from . import slint as native
 11from . import language
 12
 13import types
 14import logging
 15import copy
 16import typing
 17from typing import Any
 18import pathlib
 19from .models import ListModel, Model
 20from .slint import (
 21    Image,
 22    Color,
 23    Brush,
 24    Keys,
 25    DataTransfer,
 26    LogicalPosition,
 27    LogicalSize,
 28    StyledText,
 29    Timer,
 30    TimerMode,
 31)
 32from .loop import SlintEventLoop
 33from pathlib import Path
 34from collections.abc import Coroutine
 35import asyncio
 36import gettext
 37import gzip
 38import base64
 39
 40
 41Struct = native.PyStruct
 42
 43
 44class CompileError(Exception):
 45    message: str
 46    """The error message that produced this compile error."""
 47
 48    diagnostics: list[native.PyDiagnostic]
 49    """A list of detailed diagnostics that were produced as part of the compilation."""
 50
 51    def __init__(self, message: str, diagnostics: list[native.PyDiagnostic]):
 52        """@private"""
 53        super().__init__(message)
 54        self.message = message
 55        self.diagnostics = diagnostics
 56        for diag in self.diagnostics:
 57            self.add_note(str(diag))
 58
 59
 60class Component:
 61    """Component is the base class for all instances of Slint components. Use the member functions to show or hide the
 62    window, or spin the event loop."""
 63
 64    __instance__: native.ComponentInstance
 65
 66    def show(self) -> None:
 67        """Shows the window on the screen."""
 68
 69        self.__instance__.show()
 70
 71    def hide(self) -> None:
 72        """Hides the window from the screen."""
 73
 74        self.__instance__.hide()
 75
 76    def run(self) -> None:
 77        """Shows the window, runs the event loop, hides it when the loop is quit, and returns."""
 78        self.show()
 79        run_event_loop()
 80        self.hide()
 81
 82
 83def _normalize_prop(name: str) -> str:
 84    return name.replace("-", "_")
 85
 86
 87def _build_global_class(compdef: native.ComponentDefinition, global_name: str) -> Any:
 88    properties_and_callbacks = {}
 89
 90    for prop_name in compdef.global_properties(global_name).keys():
 91        python_prop = _normalize_prop(prop_name)
 92        if python_prop in properties_and_callbacks:
 93            logging.warning(f"Duplicated property {prop_name}")
 94            continue
 95
 96        def mk_setter_getter(prop_or_callback_name: str) -> property:
 97            def getter(self: Component) -> Any:
 98                return self.__instance__.get_global_property(
 99                    global_name, prop_or_callback_name
100                )
101
102            def setter(self: Component, value: Any) -> None:
103                self.__instance__.set_global_property(
104                    global_name, prop_or_callback_name, value
105                )
106
107            return property(getter, setter)
108
109        properties_and_callbacks[python_prop] = mk_setter_getter(prop_name)
110
111    for callback_name in compdef.global_callbacks(global_name):
112        python_prop = _normalize_prop(callback_name)
113        if python_prop in properties_and_callbacks:
114            logging.warning(f"Duplicated property {prop_name}")
115            continue
116
117        def mk_setter_getter(prop_or_callback_name: str) -> property:
118            def getter(self: Component) -> typing.Callable[..., Any]:
119                def call(*args: Any) -> Any:
120                    return self.__instance__.invoke_global(
121                        global_name, prop_or_callback_name, *args
122                    )
123
124                return call
125
126            def setter(self: Component, value: typing.Callable[..., Any]) -> None:
127                self.__instance__.set_global_callback(
128                    global_name, prop_or_callback_name, value
129                )
130
131            return property(getter, setter)
132
133        properties_and_callbacks[python_prop] = mk_setter_getter(callback_name)
134
135    for function_name in compdef.global_functions(global_name):
136        python_prop = _normalize_prop(function_name)
137        if python_prop in properties_and_callbacks:
138            logging.warning(f"Duplicated function {prop_name}")
139            continue
140
141        def mk_getter(function_name: str) -> property:
142            def getter(self: Component) -> typing.Callable[..., Any]:
143                def call(*args: Any) -> Any:
144                    return self.__instance__.invoke_global(
145                        global_name, function_name, *args
146                    )
147
148                return call
149
150            return property(getter)
151
152        properties_and_callbacks[python_prop] = mk_getter(function_name)
153
154    return type("SlintGlobalClassWrapper", (), properties_and_callbacks)
155
156
157def _build_class(
158    compdef: native.ComponentDefinition,
159) -> typing.Callable[..., Component]:
160    def cls_init(self: Component, **kwargs: Any) -> Any:
161        self.__instance__ = compdef.create()
162        for name, value in self.__class__.__dict__.items():
163            if hasattr(value, "slint.callback"):
164                callback_info = getattr(value, "slint.callback")
165                name = callback_info["name"]
166
167                is_async = getattr(value, "slint.async", False)
168                if is_async:
169                    if "global_name" in callback_info:
170                        global_name = callback_info["global_name"]
171                        is_void = compdef.global_callback_returns_void(
172                            global_name, name
173                        )
174                        if is_void is None:
175                            raise AttributeError(
176                                f"Callback '{name}' in global '{global_name}' cannot be used with a callback decorator for an async function, as it is not declared in Slint component"
177                            )
178                        if not is_void:
179                            raise RuntimeError(
180                                f"Callback '{name}' in global '{global_name}' cannot be used with a callback decorator for an async function, as it doesn't return void"
181                            )
182                    else:
183                        is_void = compdef.callback_returns_void(name)
184                        if is_void is None:
185                            raise AttributeError(
186                                f"Callback '{name}' cannot be used with a callback decorator for an async function, as it is not declared in Slint component"
187                            )
188                        if not is_void:
189                            raise RuntimeError(
190                                f"Callback '{name}' cannot be used with a callback decorator for an async function, as it doesn't return void"
191                            )
192
193                def mk_callback(
194                    self: Any, callback: typing.Callable[..., Any]
195                ) -> typing.Callable[..., Any]:
196                    def invoke(*args: Any, **kwargs: Any) -> Any:
197                        return callback(self, *args, **kwargs)
198
199                    return invoke
200
201                if "global_name" in callback_info:
202                    self.__instance__.set_global_callback(
203                        callback_info["global_name"], name, mk_callback(self, value)
204                    )
205                else:
206                    self.__instance__.set_callback(name, mk_callback(self, value))
207
208        for prop, val in kwargs.items():
209            setattr(self, prop, val)
210
211    properties_and_callbacks: dict[Any, Any] = {"__init__": cls_init}
212
213    for prop_name in compdef.properties.keys():
214        python_prop = _normalize_prop(prop_name)
215        if python_prop in properties_and_callbacks:
216            logging.warning(f"Duplicated property {prop_name}")
217            continue
218
219        def mk_setter_getter(prop_or_callback_name: str) -> property:
220            def getter(self: Component) -> Any:
221                return self.__instance__.get_property(prop_or_callback_name)
222
223            def setter(self: Component, value: Any) -> None:
224                self.__instance__.set_property(prop_or_callback_name, value)
225
226            return property(getter, setter)
227
228        properties_and_callbacks[python_prop] = mk_setter_getter(prop_name)
229
230    for callback_name in compdef.callbacks:
231        python_prop = _normalize_prop(callback_name)
232        if python_prop in properties_and_callbacks:
233            logging.warning(f"Duplicated property {prop_name}")
234            continue
235
236        def mk_setter_getter(prop_or_callback_name: str) -> property:
237            def getter(self: Component) -> typing.Callable[..., Any]:
238                def call(*args: Any) -> Any:
239                    return self.__instance__.invoke(prop_or_callback_name, *args)
240
241                return call
242
243            def setter(self: Component, value: typing.Callable[..., Any]) -> None:
244                self.__instance__.set_callback(prop_or_callback_name, value)
245
246            return property(getter, setter)
247
248        properties_and_callbacks[python_prop] = mk_setter_getter(callback_name)
249
250    for function_name in compdef.functions:
251        python_prop = _normalize_prop(function_name)
252        if python_prop in properties_and_callbacks:
253            logging.warning(f"Duplicated function {prop_name}")
254            continue
255
256        def mk_getter(function_name: str) -> property:
257            def getter(self: Component) -> typing.Callable[..., Any]:
258                def call(*args: Any) -> Any:
259                    return self.__instance__.invoke(function_name, *args)
260
261                return call
262
263            return property(getter)
264
265        properties_and_callbacks[python_prop] = mk_getter(function_name)
266
267    for global_name in compdef.globals:
268        global_class = _build_global_class(compdef, global_name)
269
270        def mk_global(global_class: typing.Callable[..., Any]) -> property:
271            def global_getter(self: Component) -> Any:
272                wrapper = global_class()
273                setattr(wrapper, "__instance__", self.__instance__)
274                return wrapper
275
276            return property(global_getter)
277
278        properties_and_callbacks[global_name] = mk_global(global_class)
279
280    return type("SlintClassWrapper", (Component,), properties_and_callbacks)
281
282
283def _build_struct(name: str, struct_prototype: native.PyStruct) -> type:
284    def new_struct(cls: Any, *args: Any, **kwargs: Any) -> native.PyStruct:
285        inst = copy.copy(struct_prototype)
286
287        for prop, val in kwargs.items():
288            setattr(inst, prop, val)
289
290        return inst
291
292    type_dict = {
293        "__new__": new_struct,
294    }
295
296    return type(name, (), type_dict)
297
298
299def _load_file(
300    path: str | os.PathLike[Any] | pathlib.Path,
301    quiet: bool = False,
302    style: typing.Optional[str] = None,
303    include_paths: typing.Optional[typing.List[os.PathLike[Any] | pathlib.Path]] = None,
304    library_paths: typing.Optional[
305        typing.Dict[str, os.PathLike[Any] | pathlib.Path]
306    ] = None,
307    translation_domain: typing.Optional[str] = None,
308) -> typing.Tuple[types.SimpleNamespace, native.CompilationResult]:
309    """This function is the low-level entry point into Slint for instantiating components. It loads the `.slint` file at
310    the specified `path` and returns a namespace with all exported components as Python classes, as well as enums, and structs.
311
312    * `quiet`: Set to true to prevent any warnings during compilation from being printed to stderr.
313    * `style`: Specify a widget style.
314    * `include_paths`: Additional include paths used to look up `.slint` files imported from other `.slint` files.
315    * `library_paths`: A dictionary that maps library names to their location in the file system. This is then used to look up
316       library imports, such as `import { MyButton } from "@mylibrary";`.
317    * `translation_domain`: The domain to use for looking up the catalogue run-time translations. This must match the
318       translation domain used when extracting translations with `slint-tr-extractor`.
319
320    """
321
322    compiler = native.Compiler()
323
324    if style is not None:
325        compiler.style = style
326    if include_paths is not None:
327        compiler.include_paths = include_paths
328    if library_paths is not None:
329        compiler.library_paths = library_paths
330    if translation_domain is not None:
331        compiler.translation_domain = translation_domain
332
333    result = compiler.build_from_path(Path(path))
334
335    diagnostics = result.diagnostics
336    if diagnostics:
337        if not quiet:
338            for diag in diagnostics:
339                if diag.level == native.DiagnosticLevel.Warning:
340                    logging.warning(diag)
341                if diag.level == native.DiagnosticLevel.Note:
342                    logging.debug(diag)
343
344        errors = [
345            diag for diag in diagnostics if diag.level == native.DiagnosticLevel.Error
346        ]
347        if errors:
348            raise CompileError(f"Could not compile {path}", diagnostics)
349
350    module = types.SimpleNamespace()
351    for comp_name in result.component_names:
352        wrapper_class = _build_class(result.component(comp_name))
353
354        setattr(module, comp_name, wrapper_class)
355
356    structs, enums = result.structs_and_enums
357
358    for name, struct_prototype in structs.items():
359        name = _normalize_prop(name)
360        struct_wrapper = _build_struct(name, struct_prototype)
361        setattr(module, name, struct_wrapper)
362
363    for name, enum_class in enums.items():
364        name = _normalize_prop(name)
365        setattr(module, name, enum_class)
366
367    for orig_name, new_name in result.named_exports:
368        orig_name = _normalize_prop(orig_name)
369        new_name = _normalize_prop(new_name)
370        setattr(module, new_name, getattr(module, orig_name))
371
372    return (module, result)
373
374
375def load_file(
376    path: str | os.PathLike[Any] | pathlib.Path,
377    quiet: bool = False,
378    style: typing.Optional[str] = None,
379    include_paths: typing.Optional[typing.List[os.PathLike[Any] | pathlib.Path]] = None,
380    library_paths: typing.Optional[
381        typing.Dict[str, os.PathLike[Any] | pathlib.Path]
382    ] = None,
383    translation_domain: typing.Optional[str] = None,
384) -> types.SimpleNamespace:
385    """This function is the low-level entry point into Slint for instantiating components. It loads the `.slint` file at
386    the specified `path` and returns a namespace with all exported components as Python classes, as well as enums, and structs.
387
388    * `quiet`: Set to true to prevent any warnings during compilation from being printed to stderr.
389    * `style`: Specify a widget style.
390    * `include_paths`: Additional include paths used to look up `.slint` files imported from other `.slint` files.
391    * `library_paths`: A dictionary that maps library names to their location in the file system. This is then used to look up
392       library imports, such as `import { MyButton } from "@mylibrary";`.
393    * `translation_domain`: The domain to use for looking up the catalogue run-time translations. This must match the
394       translation domain used when extracting translations with `slint-tr-extractor`.
395
396    """
397
398    return _load_file(
399        path, quiet, style, include_paths, library_paths, translation_domain
400    )[0]
401
402
403def _load_file_checked(
404    path: str | os.PathLike[Any] | pathlib.Path,
405    expected_api_base64_compressed: str,
406    generated_file: str | os.PathLike[Any] | pathlib.Path,
407) -> types.SimpleNamespace:
408    """@private"""
409
410    module, compilation_result = _load_file(path)
411
412    expected_api = gzip.decompress(
413        base64.standard_b64decode(expected_api_base64_compressed)
414    ).decode("utf-8")
415
416    generated_api_module = native.GeneratedAPI(path=generated_file, json=expected_api)
417    actual_api_module = compilation_result.generated_api
418
419    generated_api_module.compare_generated_vs_actual(
420        generated=generated_api_module, actual=actual_api_module
421    )
422
423    return module
424
425
426class SlintAutoLoader:
427    def __init__(self, base_dir: Path | None = None):
428        self.local_dirs: typing.List[Path] | None = None
429        if base_dir:
430            self.local_dirs = [base_dir]
431
432    def __getattr__(self, name: str) -> Any:
433        for path in self.local_dirs or sys.path:
434            dir_candidate = Path(path) / name
435            if os.path.isdir(dir_candidate):
436                loader = SlintAutoLoader(dir_candidate)
437                setattr(self, name, loader)
438                return loader
439
440            file_candidate = dir_candidate.with_suffix(".slint")
441            if os.path.isfile(file_candidate):
442                type_namespace = load_file(file_candidate)
443                setattr(self, name, type_namespace)
444                return type_namespace
445
446            dir_candidate = Path(path) / name.replace("_", "-")
447            file_candidate = dir_candidate.with_suffix(".slint")
448            if os.path.isfile(file_candidate):
449                type_namespace = load_file(file_candidate)
450                setattr(self, name, type_namespace)
451                return type_namespace
452
453        return None
454
455
456loader = SlintAutoLoader()
457"""Use the global `loader` object to load Slint files from the file system. It exposes two stages of attributes:
4581. Any lookup of an attribute in the loader tries to match a file in `sys.path` with the `.slint` extension. For example
459   `loader.my_component` looks for a file `my_component.slint` in the directories in `sys.path`.
4602. Any lookup in the object returned by the first stage tries to match an exported component in the loaded file, or a
461   struct, or enum. For example `loader.my_component.MyComponent` looks for an *exported* component named `MyComponent`
462   in the file `my_component.slint`.
463
464**Note:** The first entry in the module search path `sys.path` is the directory that contains the input script.
465
466Example:
467```python
468import slint
469# Look for a file `main.slint` in the current directory,
470# #load & compile it, and instantiate the exported `MainWindow` component
471main_window = slint.loader.main_window.MainWindow()
472main_window.show()
473...
474```
475"""
476
477
478def _callback_decorator(
479    callable: typing.Callable[..., Any], info: typing.Dict[str, Any]
480) -> typing.Callable[..., Any]:
481    if "name" not in info:
482        info["name"] = typing.cast(Any, callable).__name__
483    setattr(callable, "slint.callback", info)
484
485    try:
486        import inspect
487
488        if inspect.iscoroutinefunction(callable):
489
490            def run_as_task(*args, **kwargs) -> None:
491                loop = asyncio.get_event_loop()
492                loop.create_task(callable(*args, **kwargs))
493
494            setattr(run_as_task, "slint.callback", info)
495            setattr(run_as_task, "slint.async", True)
496            return run_as_task
497    except ImportError:
498        pass
499
500    return callable
501
502
503def callback(
504    global_name: typing.Callable[..., Any] | str | None = None, name: str | None = None
505) -> typing.Callable[..., Any]:
506    """Use the callback decorator to mark a method as a callback that can be invoked from the Slint component.
507
508    For the decorator to work, the method must be a member of a class that is Slint component.
509
510    Example:
511    ```python
512    import slint
513
514    class AppMainWindow(slint.loader.main_window.MainWindow):
515
516        # Automatically connected to a callback button_clicked()
517        # in main_window.slint's MainWindow.
518        @slint.callback()
519        def button_clicked(self):
520            print("Button clicked")
521
522    ...
523    ```
524
525    If your Python method has a different name from the Slint component's callback, use the `name` parameter to specify
526    the correct name. Similarly, use the `global_name` parameter to specify the name of the correct global singleton in
527    the Slint component.
528
529    **Note:** The callback decorator can also be used with async functions. They will be run as task in the asyncio event loop.
530    This is only supported for callbacks that don't return any value, and requires Python >= 3.13.
531    """
532
533    if callable(global_name):
534        callback = global_name
535        return _callback_decorator(callback, {})
536    else:
537        info = {}
538        if name:
539            info["name"] = name
540        if global_name:
541            info["global_name"] = global_name
542        return lambda callback: _callback_decorator(callback, info)
543
544
545def set_xdg_app_id(app_id: str) -> None:
546    """Sets the application id for use on Wayland or X11 with [xdg](https://specifications.freedesktop.org/desktop-entry-spec/latest/)
547    compliant window managers. This id must be set before the window is shown; it only applies to Wayland or X11."""
548
549    native.set_xdg_app_id(app_id)
550
551
552quit_event = asyncio.Event()
553
554
555def run_event_loop(
556    main_coro: typing.Optional[Coroutine[None, None, None]] = None,
557) -> None:
558    """Runs the main Slint event loop. If specified, the coroutine `main_coro` is run in parallel. The event loop doesn't
559    terminate when the coroutine finishes, it terminates when calling `quit_event_loop()`.
560
561    Example:
562    ```python
563    import slint
564
565    ...
566    image_model: slint.ListModel[slint.Image] = slint.ListModel()
567    ...
568
569    async def main_receiver(image_model: slint.ListModel) -> None:
570        async with aiohttp.ClientSession() as session:
571            async with session.get("http://some.server/svg-image") as response:
572                svg = await response.read()
573                image = slint.Image.from_svg_data(svg)
574                image_model.append(image)
575
576    ...
577    slint.run_event_loop(main_receiver(image_model))
578    ```
579
580    """
581
582    async def run_inner() -> None:
583        global quit_event
584        loop = typing.cast(SlintEventLoop, asyncio.get_event_loop())
585
586        quit_task = asyncio.ensure_future(quit_event.wait(), loop=loop)
587
588        tasks: typing.List[asyncio.Task[typing.Any]] = [quit_task]
589
590        main_task = None
591        if main_coro:
592            main_task = loop.create_task(main_coro)
593            tasks.append(main_task)
594
595        done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
596
597        if main_task is not None and main_task in done:
598            main_task.result()  # propagate exception if thrown
599            if quit_task in pending:
600                await quit_event.wait()
601
602    global quit_event
603    quit_event = asyncio.Event()
604    asyncio.run(run_inner(), debug=False, loop_factory=SlintEventLoop)
605
606
607def quit_event_loop() -> None:
608    """Quits the running event loop in the next event processing cycle. This will make an earlier call to `run_event_loop()`
609    return."""
610    global quit_event
611    quit_event.set()
612
613
614def init_translations(translations: typing.Optional[gettext.GNUTranslations]) -> None:
615    """Installs the specified translations object to handle translations originating from the Slint code.
616
617    Example:
618    ```python
619    import gettext
620    import slint
621
622    translations_dir = os.path.join(os.path.dirname(__file__), "lang")
623    try:
624        translations = gettext.translation("my_app", translations_dir, ["de"])
625        slint.install_translations(translations)
626    except OSError:
627        pass
628    ```
629    """
630    native.init_translations(translations)
631
632
633__all__ = [
634    "CompileError",
635    "Component",
636    "load_file",
637    "_load_file_checked",
638    "loader",
639    "Image",
640    "Color",
641    "Brush",
642    "Keys",
643    "DataTransfer",
644    "LogicalPosition",
645    "LogicalSize",
646    "StyledText",
647    "Model",
648    "ListModel",
649    "Timer",
650    "TimerMode",
651    "set_xdg_app_id",
652    "callback",
653    "run_event_loop",
654    "quit_event_loop",
655    "init_translations",
656    "language",
657]
class CompileError(builtins.Exception):
45class CompileError(Exception):
46    message: str
47    """The error message that produced this compile error."""
48
49    diagnostics: list[native.PyDiagnostic]
50    """A list of detailed diagnostics that were produced as part of the compilation."""
51
52    def __init__(self, message: str, diagnostics: list[native.PyDiagnostic]):
53        """@private"""
54        super().__init__(message)
55        self.message = message
56        self.diagnostics = diagnostics
57        for diag in self.diagnostics:
58            self.add_note(str(diag))

Common base class for all non-exit exceptions.

message: str

The error message that produced this compile error.

diagnostics: list[PyDiagnostic]

A list of detailed diagnostics that were produced as part of the compilation.

class Component:
61class Component:
62    """Component is the base class for all instances of Slint components. Use the member functions to show or hide the
63    window, or spin the event loop."""
64
65    __instance__: native.ComponentInstance
66
67    def show(self) -> None:
68        """Shows the window on the screen."""
69
70        self.__instance__.show()
71
72    def hide(self) -> None:
73        """Hides the window from the screen."""
74
75        self.__instance__.hide()
76
77    def run(self) -> None:
78        """Shows the window, runs the event loop, hides it when the loop is quit, and returns."""
79        self.show()
80        run_event_loop()
81        self.hide()

Component is the base class for all instances of Slint components. Use the member functions to show or hide the window, or spin the event loop.

def show(self) -> None:
67    def show(self) -> None:
68        """Shows the window on the screen."""
69
70        self.__instance__.show()

Shows the window on the screen.

def hide(self) -> None:
72    def hide(self) -> None:
73        """Hides the window from the screen."""
74
75        self.__instance__.hide()

Hides the window from the screen.

def run(self) -> None:
77    def run(self) -> None:
78        """Shows the window, runs the event loop, hides it when the loop is quit, and returns."""
79        self.show()
80        run_event_loop()
81        self.hide()

Shows the window, runs the event loop, hides it when the loop is quit, and returns.

def load_file( path: str | os.PathLike[typing.Any] | pathlib.Path, quiet: bool = False, style: Optional[str] = None, include_paths: Optional[List[os.PathLike[Any] | pathlib.Path]] = None, library_paths: Optional[Dict[str, os.PathLike[Any] | pathlib.Path]] = None, translation_domain: Optional[str] = None) -> types.SimpleNamespace:
376def load_file(
377    path: str | os.PathLike[Any] | pathlib.Path,
378    quiet: bool = False,
379    style: typing.Optional[str] = None,
380    include_paths: typing.Optional[typing.List[os.PathLike[Any] | pathlib.Path]] = None,
381    library_paths: typing.Optional[
382        typing.Dict[str, os.PathLike[Any] | pathlib.Path]
383    ] = None,
384    translation_domain: typing.Optional[str] = None,
385) -> types.SimpleNamespace:
386    """This function is the low-level entry point into Slint for instantiating components. It loads the `.slint` file at
387    the specified `path` and returns a namespace with all exported components as Python classes, as well as enums, and structs.
388
389    * `quiet`: Set to true to prevent any warnings during compilation from being printed to stderr.
390    * `style`: Specify a widget style.
391    * `include_paths`: Additional include paths used to look up `.slint` files imported from other `.slint` files.
392    * `library_paths`: A dictionary that maps library names to their location in the file system. This is then used to look up
393       library imports, such as `import { MyButton } from "@mylibrary";`.
394    * `translation_domain`: The domain to use for looking up the catalogue run-time translations. This must match the
395       translation domain used when extracting translations with `slint-tr-extractor`.
396
397    """
398
399    return _load_file(
400        path, quiet, style, include_paths, library_paths, translation_domain
401    )[0]

This function is the low-level entry point into Slint for instantiating components. It loads the .slint file at the specified path and returns a namespace with all exported components as Python classes, as well as enums, and structs.

  • quiet: Set to true to prevent any warnings during compilation from being printed to stderr.
  • style: Specify a widget style.
  • include_paths: Additional include paths used to look up .slint files imported from other .slint files.
  • library_paths: A dictionary that maps library names to their location in the file system. This is then used to look up library imports, such as import { MyButton } from "@mylibrary";.
  • translation_domain: The domain to use for looking up the catalogue run-time translations. This must match the translation domain used when extracting translations with slint-tr-extractor.
loader = <slint.SlintAutoLoader object>

Use the global loader object to load Slint files from the file system. It exposes two stages of attributes:

  1. Any lookup of an attribute in the loader tries to match a file in sys.path with the .slint extension. For example loader.my_component looks for a file my_component.slint in the directories in sys.path.
  2. Any lookup in the object returned by the first stage tries to match an exported component in the loaded file, or a struct, or enum. For example loader.my_component.MyComponent looks for an exported component named MyComponent in the file my_component.slint.

Note: The first entry in the module search path sys.path is the directory that contains the input script.

Example:

import slint
# Look for a file `main.slint` in the current directory,
# #load & compile it, and instantiate the exported `MainWindow` component
main_window = slint.loader.main_window.MainWindow()
main_window.show()
...
class Image:

Image objects can be set on Slint Image elements for display. Use Image.load_from_path to construct Image objects from a path to an image file on disk.

def load_from_path(path: str | os.PathLike[typing.Any] | pathlib.Path) -> Image:

Loads the image from the specified path. Returns None if the image can't be loaded.

def load_from_svg_data(data: Sequence[int]) -> Image:

Creates a new image from a string that describes the image in SVG format.

def load_from_array(array: Buffer) -> Image:

Creates a new image from an array-like object that implements the Buffer Protocol. Use this function to import images created by third-party modules such as matplotlib or Pillow.

The array must satisfy certain constraints to represent an image:

  • The buffer's format needs to be B (unsigned char)
  • The shape must be a tuple of (height, width, bytes-per-pixel)
  • If a stride is defined, the row stride must be equal to width * bytes-per-pixel, and the column stride must equal the bytes-per-pixel.
  • A value of 3 for bytes-per-pixel is interpreted as RGB image, a value of 4 means RGBA.

Example of importing a matplot figure into an image:

import slint
import matplotlib

from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure

fig = Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasAgg(fig)
ax = fig.add_subplot()
ax.plot([1, 2, 3])
canvas.draw()

buffer = canvas.buffer_rgba()
img = slint.Image.load_from_array(buffer)

Example of loading an image with Pillow:

import slint
from PIL import Image
import numpy as np

pil_img = Image.open("hello.jpeg")
array = np.array(pil_img)
img = slint.Image.load_from_array(array)
size: tuple[int, int]

The size of the image as tuple of width and height.

path: Optional[pathlib.Path]

The path of the image if it was loaded from disk, or None.

height: int

The height of the image in pixels.

width: int

The width of the image in pixels.

class Color:

A Color object represents a color in the RGB color space with an alpha. Each color channel and the alpha is represented as an 8-bit integer. The alpha channel is 0 for fully transparent and 255 for fully opaque.

Construct colors from a CSS color string, or by specifying the red, green, blue, and (optional) alpha channels in a dict.

def brighter(self, factor: float) -> Color:

Returns a new color that is brighter than this color by the given factor.

def darker(self, factor: float) -> Color:

Returns a new color that is darker than this color by the given factor.

def transparentize(self, factor: float) -> Color:

Returns a new version of this color with the opacity decreased by factor.

The transparency is obtained by multiplying the alpha channel by (1 - factor).

def mix(self, other: Image, factor: float) -> Color:

Returns a new color that is a mix of this color and other. The specified factor is clamped to be between 0.0 and 1.0 and then applied to this color, while 1.0 - factor is applied to other.

def with_alpha(self, alpha: float) -> Color:

Returns a new version of this color with the opacity set to alpha.

green: int

The green channel.

alpha: int

The alpha channel.

blue: int

The blue channel.

red: int

The red channel.

class Brush:

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.

Brushes can only be constructed from solid colors.

Note: In future, we plan to reduce this constraint and allow for declaring gradient brushes programmatically.

def is_transparent(self) -> bool:

Returns true if this brush contains a fully transparent color (alpha value is zero).

def is_opaque(self) -> bool:

Returns true if this brush is fully opaque.

def brighter(self, factor: float) -> Brush:

Returns a new version of this brush that has the brightness increased by the specified factor. This is done by calling Color.brighter on all the colors of this brush.

def darker(self, factor: float) -> Brush:

Returns a new version of this brush that has the brightness decreased by the specified factor. This is done by calling Color.darker on all the color of this brush.

def transparentize(self, amount: float) -> Brush:

Returns a new version of this brush with the opacity decreased by factor.

The transparency is obtained by multiplying the alpha channel by (1 - factor).

See also Color.transparentize.

def with_alpha(self, alpha: float) -> Brush:

Returns a new version of this brush with the related color's opacities set to alpha.

color: Color

The brush's color.

class Keys:

Represents a key binding created by the @keys(...) macro in Slint.

This is an opaque type. Use str() to get a platform-native representation of the key binding (e.g. "Ctrl+A" on Linux/Windows, "⌘A" on macOS).

def from_parts(parts: list[str]) -> Keys:

Create a Keys from a list of string parts, e.g. ["Control", "Shift?", "Z"].

Each element is either a modifier name or a key name. Raises ValueError on parse failure.

class DataTransfer:

Python representation of some form of type-indexed possibly-lazy data transfer. Used for accessing the platform clipboard and drag-and-drop APIs.

DataTransfer()

Constructs an empty DataTransfer.

def set_plaintext(self, text: str) -> None:

Sets the plaintext representation of this DataTransfer. Calling this again overwrites the previous plaintext.

def fetch_plaintext(self) -> Optional[str]:

Returns the plaintext representation of this DataTransfer, or None if no plaintext is available.

def set_image(self, image: Image) -> None:

Sets the image representation of this DataTransfer. Calling this again overwrites the previous image.

def fetch_image(self) -> Optional[Image]:

Returns the image representation of this DataTransfer, or None if no image is available.

has_image: bool

True if this DataTransfer advertises an image representation.

user_data: Optional[object]

Application-internal user data attached to this DataTransfer. Use this when the drag-and-drop or clipboard operation stays inside the current Python application and you want to avoid serializing to plaintext or an image.

Reading returns the Python object previously assigned, or None if none was set (or the user data was set by a non-Python binding). Assigning None clears any previously attached Python user data.

has_plaintext: bool

True if this DataTransfer advertises a plaintext representation.

class LogicalPosition:

A 2D position in logical pixels.

x

The horizontal coordinate.

y

The vertical coordinate.

class LogicalSize:

A 2D size in logical pixels.

width

The width.

height

The height.

class StyledText:

Python wrapper for Slint's styled-text type.

def from_plain_text(text):

Creates styled text from plain text.

def from_markdown(markdown):

Parses markdown and returns a StyledText object.

Raises a ValueError if the markdown contains unsupported syntax.

class Model(builtins.PyModelBase, collections.abc.Iterable[T], typing.Generic[T]):
12class Model[T](native.PyModelBase, Iterable[T]):
13    """Model is the base class for feeding dynamic data into Slint views.
14
15    Subclass Model to implement your own models, or use `ListModel` to wrap a list.
16
17    Models are iterable and can be used in for loops."""
18
19    def __new__(cls, *args: Any) -> typing.Self:
20        return super().__new__(cls)
21
22    def __init__(self) -> None:
23        self.init_self(self)
24
25    def __len__(self) -> int:
26        return self.row_count()
27
28    def __getitem__(self, index: int) -> typing.Optional[T]:
29        return self.row_data(index)
30
31    def __setitem__(self, index: int, value: T) -> None:
32        self.set_row_data(index, value)
33
34    def __iter__(self) -> Iterator[T]:
35        return ModelIterator(self)
36
37    def set_row_data(self, row: int, value: T) -> None:
38        """Call this method on mutable models to change the data for the given row.
39        The UI will also call this method when modifying a model's data.
40        Re-implement this method in a sub-class to handle the change."""
41        super().set_row_data(row, value)
42
43    @abstractmethod
44    def row_data(self, row: int) -> typing.Optional[T]:
45        """Returns the data for the given row.
46        Re-implement this method in a sub-class to provide the data."""
47        return cast(T, super().row_data(row))
48
49    def notify_row_changed(self, row: int) -> None:
50        """Call this method from a sub-class to notify the views that a row has changed."""
51        super().notify_row_changed(row)
52
53    def notify_row_removed(self, row: int, count: int) -> None:
54        """Call this method from a sub-class to notify the views that
55        `count` rows have been removed starting at `row`."""
56        super().notify_row_removed(row, count)
57
58    def notify_row_added(self, row: int, count: int) -> None:
59        """Call this method from a sub-class to notify the views that
60        `count` rows have been added starting at `row`."""
61        super().notify_row_added(row, count)

Model is the base class for feeding dynamic data into Slint views.

Subclass Model to implement your own models, or use ListModel to wrap a list.

Models are iterable and can be used in for loops.

def set_row_data(self, row: int, value: T) -> None:
37    def set_row_data(self, row: int, value: T) -> None:
38        """Call this method on mutable models to change the data for the given row.
39        The UI will also call this method when modifying a model's data.
40        Re-implement this method in a sub-class to handle the change."""
41        super().set_row_data(row, value)

Call this method on mutable models to change the data for the given row. The UI will also call this method when modifying a model's data. Re-implement this method in a sub-class to handle the change.

@abstractmethod
def row_data(self, row: int) -> Optional[T]:
43    @abstractmethod
44    def row_data(self, row: int) -> typing.Optional[T]:
45        """Returns the data for the given row.
46        Re-implement this method in a sub-class to provide the data."""
47        return cast(T, super().row_data(row))

Returns the data for the given row. Re-implement this method in a sub-class to provide the data.

def notify_row_changed(self, /, index):

Call this method from a sub-class to notify the views that a row has changed.

def notify_row_removed(self, /, index, count):

Call this method from a sub-class to notify the views that count rows have been removed starting at row.

def notify_row_added(self, /, index, count):

Call this method from a sub-class to notify the views that count rows have been added starting at row.

class ListModel(slint.Model[T], typing.Generic[T]):
 64class ListModel[T](Model[T]):
 65    """ListModel is a `Model` that stores its data in a Python list.
 66
 67    Construct a ListMode from an iterable (such as a list itself).
 68    Use `ListModel.append()` to add items to the model, and use the
 69    `del` statement to remove items.
 70
 71    Any changes to the model are automatically reflected in the views
 72    in UI they're used with.
 73    """
 74
 75    def __init__(self, iterable: typing.Optional[Iterable[T]] = None):
 76        """Constructs a new ListModel from the give iterable. All the values
 77        the iterable produces are stored in a list."""
 78
 79        super().__init__()
 80        if iterable is not None:
 81            self.list = list(iterable)
 82        else:
 83            self.list = []
 84
 85    def row_count(self) -> int:
 86        return len(self.list)
 87
 88    def row_data(self, row: int) -> typing.Optional[T]:
 89        return self.list[row]
 90
 91    def set_row_data(self, row: int, value: T) -> None:
 92        self.list[row] = value
 93        super().notify_row_changed(row)
 94
 95    def __delitem__(self, key: int | slice) -> None:
 96        if isinstance(key, slice):
 97            start, stop, step = key.indices(len(self.list))
 98            del self.list[key]
 99            count = len(range(start, stop, step))
100            super().notify_row_removed(start, count)
101        else:
102            del self.list[key]
103            super().notify_row_removed(key, 1)
104
105    def append(self, value: T) -> None:
106        """Appends the value to the end of the list."""
107        index = len(self.list)
108        self.list.append(value)
109        super().notify_row_added(index, 1)
110
111    def insert(self, index: int, value: T) -> None:
112        """Inserts the value at the given index. Negative indices and indices
113        past the end of the list behave like `list.insert`."""
114        clamped = max(0, min(index, len(self.list)))
115        self.list.insert(clamped, value)
116        super().notify_row_added(clamped, 1)

ListModel is a Model that stores its data in a Python list.

Construct a ListMode from an iterable (such as a list itself). Use ListModel.append() to add items to the model, and use the del statement to remove items.

Any changes to the model are automatically reflected in the views in UI they're used with.

ListModel(iterable: Optional[Iterable[T]] = None)
75    def __init__(self, iterable: typing.Optional[Iterable[T]] = None):
76        """Constructs a new ListModel from the give iterable. All the values
77        the iterable produces are stored in a list."""
78
79        super().__init__()
80        if iterable is not None:
81            self.list = list(iterable)
82        else:
83            self.list = []

Constructs a new ListModel from the give iterable. All the values the iterable produces are stored in a list.

def row_count(self) -> int:
85    def row_count(self) -> int:
86        return len(self.list)
def row_data(self, row: int) -> Optional[T]:
88    def row_data(self, row: int) -> typing.Optional[T]:
89        return self.list[row]

Returns the data for the given row. Re-implement this method in a sub-class to provide the data.

def set_row_data(self, row: int, value: T) -> None:
91    def set_row_data(self, row: int, value: T) -> None:
92        self.list[row] = value
93        super().notify_row_changed(row)

Call this method on mutable models to change the data for the given row. The UI will also call this method when modifying a model's data. Re-implement this method in a sub-class to handle the change.

def append(self, value: T) -> None:
105    def append(self, value: T) -> None:
106        """Appends the value to the end of the list."""
107        index = len(self.list)
108        self.list.append(value)
109        super().notify_row_added(index, 1)

Appends the value to the end of the list.

def insert(self, index: int, value: T) -> None:
111    def insert(self, index: int, value: T) -> None:
112        """Inserts the value at the given index. Negative indices and indices
113        past the end of the list behave like `list.insert`."""
114        clamped = max(0, min(index, len(self.list)))
115        self.list.insert(clamped, value)
116        super().notify_row_added(clamped, 1)

Inserts the value at the given index. Negative indices and indices past the end of the list behave like list.insert.

class Timer:

Timer is a handle to the timer system that triggers a callback after a specified period of time.

Use Timer.start() to create a timer that that repeatedly triggers a callback, or Timer.single_shot() to trigger a callback only once.

The timer will automatically stop when garbage collected. You must keep the Timer object around for as long as you want the timer to keep firing.

class AppWindow(...)
    def __init__(self):
        super().__init__()
        self.my_timer = None

    @slint.callback
    def button_clicked(self):
        self.my_timer = slint.Timer()
        self.my_timer.start(timedelta(seconds=1), self.do_something)

    def do_something(self):
        pass

Timers can only be used in the thread that runs the Slint event loop. They don't fire if used in another thread.

def start( self, mode: TimerMode, interval: datetime.timedelta, callback: Any) -> None:

Starts the timer with the given mode and interval, in order for the callback to called when the timer fires. If the timer has been started previously and not fired yet, then it will be restarted.

Arguments:

  • mode: The timer mode to apply, i.e. whether to repeatedly fire the timer or just once.
  • interval: The duration from now until when the timer should fire the first time, and subsequently for TimerMode.Repeated timers.
  • callback: The function to call when the time has been reached or exceeded.
def single_shot(duration: datetime.timedelta, callback: Any) -> None:

Starts the timer with the duration and the callback to called when the timer fires. It is fired only once and then deleted.

Arguments:

  • duration: The duration from now until when the timer should fire.
  • callback: The function to call when the time has been reached or exceeded.
def stop(self) -> None:

Stops the previously started timer. Does nothing if the timer has never been started.

def restart(self) -> None:

Restarts the timer. If the timer was previously started by calling Timer.start() with a duration and callback, then the time when the callback will be next invoked is re-calculated to be in the specified duration relative to when this function is called.

Does nothing if the timer was never started.

running: bool

Set to true if the timer is running; false otherwise.

interval: datetime.timedelta

The duration of timer.

When setting this property and the timer is running (see Timer.running), then the time when the callback will be next invoked is re-calculated to be in the specified duration relative to when this property is set.

class TimerMode:

The TimerMode specifies what should happen after the timer fired.

Used by the Timer.start() function.

SingleShot = TimerMode.SingleShot
Repeated = TimerMode.Repeated
def set_xdg_app_id(app_id: str) -> None:
546def set_xdg_app_id(app_id: str) -> None:
547    """Sets the application id for use on Wayland or X11 with [xdg](https://specifications.freedesktop.org/desktop-entry-spec/latest/)
548    compliant window managers. This id must be set before the window is shown; it only applies to Wayland or X11."""
549
550    native.set_xdg_app_id(app_id)

Sets the application id for use on Wayland or X11 with xdg compliant window managers. This id must be set before the window is shown; it only applies to Wayland or X11.

def callback( global_name: Union[Callable[..., Any], str, NoneType] = None, name: str | None = None) -> Callable[..., Any]:
504def callback(
505    global_name: typing.Callable[..., Any] | str | None = None, name: str | None = None
506) -> typing.Callable[..., Any]:
507    """Use the callback decorator to mark a method as a callback that can be invoked from the Slint component.
508
509    For the decorator to work, the method must be a member of a class that is Slint component.
510
511    Example:
512    ```python
513    import slint
514
515    class AppMainWindow(slint.loader.main_window.MainWindow):
516
517        # Automatically connected to a callback button_clicked()
518        # in main_window.slint's MainWindow.
519        @slint.callback()
520        def button_clicked(self):
521            print("Button clicked")
522
523    ...
524    ```
525
526    If your Python method has a different name from the Slint component's callback, use the `name` parameter to specify
527    the correct name. Similarly, use the `global_name` parameter to specify the name of the correct global singleton in
528    the Slint component.
529
530    **Note:** The callback decorator can also be used with async functions. They will be run as task in the asyncio event loop.
531    This is only supported for callbacks that don't return any value, and requires Python >= 3.13.
532    """
533
534    if callable(global_name):
535        callback = global_name
536        return _callback_decorator(callback, {})
537    else:
538        info = {}
539        if name:
540            info["name"] = name
541        if global_name:
542            info["global_name"] = global_name
543        return lambda callback: _callback_decorator(callback, info)

Use the callback decorator to mark a method as a callback that can be invoked from the Slint component.

For the decorator to work, the method must be a member of a class that is Slint component.

Example:

import slint

class AppMainWindow(slint.loader.main_window.MainWindow):

    # Automatically connected to a callback button_clicked()
    # in main_window.slint's MainWindow.
    @slint.callback()
    def button_clicked(self):
        print("Button clicked")

...

If your Python method has a different name from the Slint component's callback, use the name parameter to specify the correct name. Similarly, use the global_name parameter to specify the name of the correct global singleton in the Slint component.

Note: The callback decorator can also be used with async functions. They will be run as task in the asyncio event loop. This is only supported for callbacks that don't return any value, and requires Python >= 3.13.

def run_event_loop(main_coro: Optional[Coroutine[None, None, None]] = None) -> None:
556def run_event_loop(
557    main_coro: typing.Optional[Coroutine[None, None, None]] = None,
558) -> None:
559    """Runs the main Slint event loop. If specified, the coroutine `main_coro` is run in parallel. The event loop doesn't
560    terminate when the coroutine finishes, it terminates when calling `quit_event_loop()`.
561
562    Example:
563    ```python
564    import slint
565
566    ...
567    image_model: slint.ListModel[slint.Image] = slint.ListModel()
568    ...
569
570    async def main_receiver(image_model: slint.ListModel) -> None:
571        async with aiohttp.ClientSession() as session:
572            async with session.get("http://some.server/svg-image") as response:
573                svg = await response.read()
574                image = slint.Image.from_svg_data(svg)
575                image_model.append(image)
576
577    ...
578    slint.run_event_loop(main_receiver(image_model))
579    ```
580
581    """
582
583    async def run_inner() -> None:
584        global quit_event
585        loop = typing.cast(SlintEventLoop, asyncio.get_event_loop())
586
587        quit_task = asyncio.ensure_future(quit_event.wait(), loop=loop)
588
589        tasks: typing.List[asyncio.Task[typing.Any]] = [quit_task]
590
591        main_task = None
592        if main_coro:
593            main_task = loop.create_task(main_coro)
594            tasks.append(main_task)
595
596        done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
597
598        if main_task is not None and main_task in done:
599            main_task.result()  # propagate exception if thrown
600            if quit_task in pending:
601                await quit_event.wait()
602
603    global quit_event
604    quit_event = asyncio.Event()
605    asyncio.run(run_inner(), debug=False, loop_factory=SlintEventLoop)

Runs the main Slint event loop. If specified, the coroutine main_coro is run in parallel. The event loop doesn't terminate when the coroutine finishes, it terminates when calling quit_event_loop().

Example:

import slint

...
image_model: slint.ListModel[slint.Image] = slint.ListModel()
...

async def main_receiver(image_model: slint.ListModel) -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get("http://some.server/svg-image") as response:
            svg = await response.read()
            image = slint.Image.from_svg_data(svg)
            image_model.append(image)

...
slint.run_event_loop(main_receiver(image_model))
def quit_event_loop() -> None:
608def quit_event_loop() -> None:
609    """Quits the running event loop in the next event processing cycle. This will make an earlier call to `run_event_loop()`
610    return."""
611    global quit_event
612    quit_event.set()

Quits the running event loop in the next event processing cycle. This will make an earlier call to run_event_loop() return.

def init_translations(translations: Optional[gettext.GNUTranslations]) -> None:
615def init_translations(translations: typing.Optional[gettext.GNUTranslations]) -> None:
616    """Installs the specified translations object to handle translations originating from the Slint code.
617
618    Example:
619    ```python
620    import gettext
621    import slint
622
623    translations_dir = os.path.join(os.path.dirname(__file__), "lang")
624    try:
625        translations = gettext.translation("my_app", translations_dir, ["de"])
626        slint.install_translations(translations)
627    except OSError:
628        pass
629    ```
630    """
631    native.init_translations(translations)

Installs the specified translations object to handle translations originating from the Slint code.

Example:

import gettext
import slint

translations_dir = os.path.join(os.path.dirname(__file__), "lang")
try:
    translations = gettext.translation("my_app", translations_dir, ["de"])
    slint.install_translations(translations)
except OSError:
    pass