Skip to content

Latest commit

 

History

History
162 lines (112 loc) · 3.63 KB

File metadata and controls

162 lines (112 loc) · 3.63 KB

Retink = React + Tkinter

Retink is a library for building reactive user interfaces in Python. It is inspired by React and uses tkinter as the backend.

Examples

1. Hello World

from retink import run, Text, component

@component
def App():
    return Text("hello"), Text("world")

run(App)

Each component is a function with the @component decorator, that returns one or more widgets.

The component whose function is run (using the run function)is the root component.

2. Counter

from retink import run, Text, Button, component, create_state

@component
def App():
    count, set_count = create_state(0)

    return Button(
        f"Clicked {count} time(s)", 
        on_click=lambda: set_count(count + 1)
    )

run(App)

Use create_state to create a stateful value. The first argument is the initial value, the second is a setter function.

3. Effects

from retink import run, Text, Button, component, create_state, create_effect

@component
def App():
    count, set_count = create_state(0)

    create_effect(lambda: print(count), [count])

    return Button(
        f"Clicked {count} time(s)", 
        on_click=lambda: set_count(count + 1)
    )

run(App)

Use create_effect to create an effect. The first argument is the function to run, the second is a list of stateful values that the function depends on.

4. View

from retink import run, Text, Button, component, create_state, create_effect

@component
def App():
    count, set_count = create_state(0)

    create_effect(lambda: print(count), [count])

    return View([
        Text(f"Clicked {count} time(s)"),
        Button("Click me", on_click=lambda: set_count(count + 1))
    ])

run(App)

Use View to group multiple widgets together. The widgets are laid out horizontally by default. But you can use row=True to lay them out vertically.

from retink import run, Text, Button, component, create_state, create_effect

@component
def App():
    count, set_count = create_state(0)

    create_effect(lambda: print(count), [count])

    return View([
        Text(f"Clicked {count} time(s)"),
        Button("Click me", on_click=lambda: set_count(count + 1)),
    ], row=True)

run(App)

Note: When we return multiple widgets from a component, they are wrapped in a View implicitly.

5. Conditional Rendering

from retink import run, Text, Button, component, create_state, create_effect

@component
def App():
    count, set_count = create_state(0)

    even_ui = Text("even")
    odd_ui = Text("odd")

    label = even_ui if count % 2 == 0 else odd_ui

    return View([
        label,
        Button("Click me", on_click=lambda: set_count(count + 1)) if count < 5 else Text("Clicked too many times")
    ])

run(App)

Since UI is just a python function, and views are just python lists, we can use python's conditional statements to render different UIs.

6. List

from retink import run, Text, Button, component, create_state, create_effect

@component
def App():
    todos, set_todos = create_state([])

    def add_todo(text):
        set_todos(todos + [text])

    return View([
        Text("Enter a todo:"),
        TextInput(on_change=add_todo),
        *(Text(text) for text in todos)
    ])

run(App)

Use * to unpack a list of widgets into a list of widgets.

7. Images

from retink import run, Image, component

@component
def App():
    return Image("path/to/image.png")

run(App)

Use Image to display an image.

The todo app

See todo.py for a complete example of a todo app.

Installation

Download the repo and run pip install . in the root directory.