Tables¶
DataTable displays tabular data backed by a ListState. Mutations to the list automatically update the UI.
Basic table¶
"""Basic table — ListState-driven data table."""
import libui
from libui.declarative import (
App,
Window,
VBox,
HBox,
Label,
Button,
State,
stretchy,
DataTable,
ListState,
TextColumn,
ProgressColumn,
)
async def main():
app = App()
status = State("Click a row.")
data = ListState(
[
{"name": "Alice", "role": "Engineer", "score": 85},
{"name": "Bob", "role": "Designer", "score": 72},
{"name": "Carol", "role": "Manager", "score": 90},
]
)
counter = State(len(data))
def add_row():
counter.update(lambda n: n + 1)
data.append(
{
"name": f"Person {counter.value}",
"role": "New",
"score": 50,
}
)
app.build(
window=Window(
"Basic Table",
500,
350,
child=VBox(
Label(text=status),
stretchy(
DataTable(
data,
TextColumn("Name", key="name"),
TextColumn("Role", key="role"),
ProgressColumn("Score", key="score"),
on_row_clicked=lambda row: status.set(
f"Clicked: {data[row]['name']}"
),
)
),
HBox(
Button("Add Row", on_clicked=add_row),
Button(
"Remove Last",
on_clicked=lambda: data.pop() if len(data) else None,
),
),
),
)
)
app.show()
await app.wait()
libui.run(main())
Each row is a dictionary. Column descriptors map dictionary keys to table columns:
TextColumn("Name", key="name")— displaysrow["name"]as textProgressColumn("Score", key="score")— displaysrow["score"]as a progress bar (0-100)
Editable table¶
Columns can be made editable so users can modify data in place:
"""Editable table — inline editing with CheckboxTextColumn."""
import libui
from libui.declarative import (
App,
Window,
VBox,
Label,
State,
stretchy,
DataTable,
ListState,
TextColumn,
CheckboxTextColumn,
)
async def main():
app = App()
status = State("Edit cells directly in the table.")
data = ListState(
[
{"done": 1, "task": "Write documentation", "notes": "In progress"},
{"done": 0, "task": "Fix bug #42", "notes": "Investigate crash"},
{"done": 1, "task": "Review PR", "notes": "Approved"},
{"done": 0, "task": "Deploy v2.0", "notes": "Waiting on tests"},
]
)
app.build(
window=Window(
"Editable Table",
550,
300,
child=VBox(
Label(text=status),
stretchy(
DataTable(
data,
CheckboxTextColumn(
"Task",
checkbox_key="done",
text_key="task",
checkbox_editable=True,
text_editable=True,
),
TextColumn("Notes", key="notes", editable=True),
on_row_clicked=lambda row: status.set(
f"Row {row}: {data[row]['task']} "
f"({'done' if data[row]['done'] else 'pending'})"
),
)
),
),
)
)
app.show()
await app.wait()
libui.run(main())
TextColumn(..., editable=True) allows inline text editing. CheckboxColumn and CheckboxTextColumn support editable checkboxes.
Column types reference¶
Column |
Description |
Key parameters |
|---|---|---|
|
Text display/edit |
|
|
Checkbox |
|
|
Checkbox + text |
|
|
Progress bar (0-100) |
|
|
Clickable button |
|
|
Image display |
|
|
Image + text |
|
Table events¶
DataTable supports several event callbacks:
DataTable(
data,
*columns,
on_row_clicked=lambda row: ..., # single click
on_row_double_clicked=lambda row: ..., # double click
on_header_clicked=lambda col: ..., # header click
on_selection_changed=lambda: ..., # selection change
)
Dynamic updates¶
Since DataTable is backed by ListState, any mutation automatically updates the UI:
data.append({"name": "New item", "score": 50}) # row appears
data[0] = {"name": "Updated", "score": 99} # row updates
data.pop() # row disappears