Base Elements#

Base Elements are the building blocks for an Edifice application.

Each Base Element manages an underlying QWidget.

All Base Elements in this module inherit from QtWidgetElement and its props. This means that all Base Elements can be made to respond to clicks by passing a handler function to the on_click prop. All Base Elements are stylable using the style prop, see Styling.

QtWidgetElement([style, tool_tip, cursor, ...])

Base Qt Widget.

Base Elements can roughly be divided into Root Elements, Layout Elements, and Content Elements.

Root Base Elements#

The root parent Element of every Edifice application is a Window.

Or an ExportList for exporting components to a normal PySide6/PyQt6 app.

Window([title, icon, menu, _on_open, ...])

The root View element of an App which runs in an operating system window.

ExportList()

The root element for an App which does App.export_widgets().

Layout Base Elements#

Each Layout Base Element manages an underlying QLayout, and can have children (like the <div> HTML tag).

To render a Layout Base Element, always use the with statement and indent the element’s children:

with VBoxView():
    with HBoxView():
        Label("Hello")
        Label("World")

All of the Layout Base Elements have the name suffix View.

VBoxView(**kwargs)

Vertical column layout view for child elements.

HBoxView(**kwargs)

Horizontal row layout view for child elements.

FixView(**kwargs)

View layout for child widgets with fixed position.

VScrollView(**kwargs)

Scrollable vertical column layout widget for grouping children together.

HScrollView(**kwargs)

Scrollable horizontal row layout widget for grouping children together.

FixScrollView(**kwargs)

Scrollable layout widget for child widgets with fixed position.

TabView([labels])

Layout widget with multiple tabs.

GridView([layout, key_to_code])

Grid layout widget for rendering children on a 2D rectangular grid.

TableGridView([row_stretch, column_stretch, ...])

Table-style grid layout displays its children as aligned rows of columns.

TableGridRow()

Row Element of a TableGridView.

FlowView(**kwargs)

Flow-style layout widget.

WindowPopView([title, icon, on_close, ...])

Pop-up Window.

Content Base Elements#

Content Base Elements render a single Qt Widget and mostly do not have children.

Label([text, selectable, word_wrap, ...])

Basic widget for displaying text.

Image(src[, aspect_ratio_mode])

Render an image.

ImageSvg(src, **kwargs)

Render an SVG image.

Icon(name[, size, collection, ...])

Display an Icon.

IconButton(name[, size, collection, ...])

Display an Icon Button.

Button([title])

Basic button widget.

ButtonView([on_trigger])

A Button where the label is the Button’s children rendered in a edifice.HBoxView.

TextInput([text, placeholder_text, ...])

Basic widget for a one line text input.

TextInputMultiline([text, placeholder_text, ...])

Basic widget for a multiline text input.

SpinInput([value, min_value, max_value, ...])

Widget for a int input value with up/down buttons.

CheckBox([checked, text, on_change])

Checkbox widget.

RadioButton([checked, text, on_change])

Radio buttons.

Slider(value[, min_value, max_value, ...])

Slider bar widget.

ProgressBar(value[, min_value, max_value, ...])

Progress bar widget.

Dropdown([selection, options, on_select, ...])

Basic widget for a dropdown menu.

Events#

Each user interaction with a Base Element generates events, and you can specify how to handle the event by providing a callback function.

These callbacks are passed into the Base Element as props, for example the on_click prop of QtWidgetElement, or the on_change prop for checkboxes, radio buttons, sliders, and text input. When the event occurs the callback function will be called with an argument describing the event.

Usually, what you want to do in an event handler callback is to update some state with a use_state() setter function.

These callbacks run in the same thread as the main application. This is handy, as you don’t have to worry about locking and race conditions. However, a lengthy operation will block the application from interacting with the user, which is generally a bad user experience.

Consider this code:

@component
def MyComponent(self):

    results, set_results = use_state("")

    def on_click(event:QMouseEvent):
        r = fetch_from_network()
        set_results(r)

    with VBoxView():
        Button("Fetch", on_click=on_click)
        if results:
            Label(results)

When the Fetch button is clicked, the event handler will call a lengthy fetch_from_network function, blocking the application from further progress. In the mean time, if the user clicks the increment button, nothing will happen until the fetch is complete.

For such cases, you can use an async callback function.

To allow the rest of the application to run while the fetch is happening, you can define the on_click handler as a coroutine:

@component
def MyComponent(self):

    results, set_results = use_state("")
    loading, set_loading = use_state(False)

    async def on_click(event:QMouseEvent):
        set_loading(True)
        r = await fetch_from_network()
        set_results(r)
        set_loading(False)

    with VBoxView():
        Button("Fetch", on_click=on_click)
        if loading:
            Label("Loading")
        elif results:
            Label(results)

While the fetch_from_network function is running, control is returned to the event loop, allowing the application to continue handling button clicks.

Note

In some cases you may have a bug from a race condition where the async event handler completes after the Element has been unmounted.

For such cases use use_async_call.

Use the use_async_call Hook for an asynchronous event handler which will cancel automatically when MyComponent is unmounted, or when the Fetch button is pressed again:

@component
def MyComponent(self):

    results, set_results = use_state("")
    loading, set_loading = use_state(False)

    async def on_click(event:QMouseEvent):
        set_loading(True)
        r = await fetch_from_network()
        set_results(r)
        set_loading(False)

    on_click_handler, cancel_click_handler = use_async_call(on_click)

    with VBoxView():
        Button("Fetch", on_click=on_click_handler)
        if loading:
            Label("Loading")
        elif results:
            Label(results)

Custom Base Elements#

Not all QtWidgets are supported by Edifice. Edifice provides CustomWidget to allow you to bind arbitrary QtWidgets to an Edifice Element.

CustomWidget()

Custom widgets that you can define.