Tabla
Una tabla de datos con cabecera fija, ordenación opcional y selección de filas. Las columnas son objetos ui.Column cuyo key es una clave de dict, un atributo o una función de la fila; render convierte un valor en cualquier widget. La tabla ordena las filas ella misma por la columna cuyo título es sort_by: solo guardas ese título y la dirección.
ui.table · Categoría: Datos · Referencia completa →


rows = [ {"name": "render.rs", "lang": "Rust", "lines": 1840}, {"name": "app.py", "lang": "Python", "lines": 512}, {"name": "theme.py", "lang": "Python", "lines": 730}, {"name": "docs.yml", "lang": "YAML", "lines": 64},]pz.container(ui.table( [ui.Column("File", "name"), ui.Column("Language", "lang", width=120), ui.Column("Lines", "lines", width=80, align="end")], rows, sort_by="Lines", descending=True, on_sort=on_sort, selected=rows[1], striped=True,), width=520)Cuándo usarlo
Sección titulada «Cuándo usarlo»- Para registros con varios campos comparables: archivos, usuarios, procesos, resultados.
- Para una sola columna de elementos, una lista de Filas es más ligera.
import pyzed as pzfrom pyzed import ui
class Files(pz.App): def __init__(self): self.rows = [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}] self.sort_by, self.descending, self.selected = "Lines", True, None
def sort(self, title): self.descending = not self.descending if self.sort_by == title else False self.sort_by = title
def view(self): return ui.table( [ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], self.rows, sort_by=self.sort_by, descending=self.descending, on_sort=self.sort, on_row_press=lambda row: setattr(self, "selected", row), selected=self.selected, )Variantes
Sección titulada «Variantes»Opciones
Sección titulada «Opciones»

Código
pz.container(ui.table([ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}, {"name": "ui.py", "lines": 1290}]), width=320)

striped=TrueCódigo
pz.container(ui.table([ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}, {"name": "ui.py", "lines": 1290}], striped=True), width=320)

selected=Código
rows = [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}, {"name": "ui.py", "lines": 1290}]pz.container(ui.table([ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], rows, selected=rows[1]), width=320)

sort_by=, descending=TrueCódigo
pz.container(ui.table([ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}, {"name": "ui.py", "lines": 1290}], sort_by="Lines", descending=True, on_sort=on_sort), width=320)

row_height=24Código
pz.container(ui.table([ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}, {"name": "ui.py", "lines": 1290}], row_height=24), width=320)

render=Código
rows = [{"job": "build", "state": "passed"}, {"job": "lint", "state": "failed"}]tint = {"passed": "success", "failed": "error"}pz.container(ui.table([ui.Column("Job", "job"), ui.Column("State", "state", width=110, render=lambda s: ui.badge(s, tint=tint[s]))], rows), width=320)

key=lambdaCódigo
people = [("Ana", 31), ("Luis", 27)]pz.container(ui.table([ui.Column("Name", lambda p: p[0]), ui.Column("Age", lambda p: p[1], width=70, align="end")], people), width=320)Estados y eventos
Sección titulada «Estados y eventos»on_row_double_press(fila) abre una fila y on_row_context(fila) muestra un menú contextual.


Código
rows = [{"name": "app.py", "size": 4}, {"name": "ui.py", "size": 12}, {"name": "README.md", "size": 2}]ui.table(["name", "size"], rows, selected=[rows[0], rows[2]], on_row_press=on_press, on_row_double_press=on_open, on_row_context=on_context, height=130)

empty=Código
ui.table(["name", "size"], [], empty="No files yet", height=100)Ejemplos
Sección titulada «Ejemplos»Celdas personalizadas
Sección titulada «Celdas personalizadas»render recibe el valor y devuelve un widget, aquí una insignia.


rows = [{"job": "build", "state": "passed"}, {"job": "lint", "state": "failed"}, {"job": "docs", "state": "running"}]tint = {"passed": "success", "failed": "error", "running": "warning"}pz.container(ui.table( [ui.Column("Job", "job"), ui.Column("State", "state", width=120, render=lambda s: ui.badge(s, tint=tint[s]))], rows,), width=400)Eventos
Sección titulada «Eventos»Tabla tiene 4 eventos propios, en la tabla de abajo. Como todo widget, también tiene los 18 eventos comunes (click, double_click, right_click, mouse_enter, drag, key_down, resize…), que se conectan con .on(...): mira Eventos y Eventos de cada componente.
| Evento | El handler recibe | Cuándo |
|---|---|---|
on_sort |
(title) |
Callable que recibe el título pulsado. |
on_row_press |
(row) |
Callable que recibe la fila pulsada. |
on_row_double_press |
(row) |
Recibe la fila con un doble clic (abrir, editar…). |
on_row_context |
(row) |
Recibe la fila con un clic derecho (un menú contextual). |
El handler recibe es lo que Pyzed le pasa a tu función: () es nada. Cualquier handler también puede ser un mensaje (un valor que no se puede llamar), que va a update().
Manejar los eventos
Sección titulada «Manejar los eventos»Los mismos eventos escritos de tres formas. Imperativa: métodos de la app que cambian self. Declarativa: los handlers producen mensajes y un único update() decide. Funcional: una función pura dibuja un estado inmutable y pide cambios con set_state(...). Mira Imperativo, declarativo y funcional.
class Files(pz.App): def __init__(self): self.rows = [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}] self.sort_by, self.descending = "Lines", True self.selected, self.opened = None, None
def sort(self, title): # on_sort: the clicked column title self.descending = not self.descending if self.sort_by == title else False self.sort_by = title
def view(self): key = "name" if self.sort_by == "File" else "lines" rows = sorted(self.rows, key=lambda r: r[key], reverse=self.descending) return ui.table( [ui.Column("File", "name"), ui.Column("Lines", "lines", width=80, align="end")], rows, sort_by=self.sort_by, descending=self.descending, on_sort=self.sort, selected=self.selected, on_row_press=lambda row: setattr(self, "selected", row), # click on_row_double_press=lambda row: setattr(self, "opened", row), # double click on_row_context=lambda row: print("menu for", row["name"]), # right click )from dataclasses import dataclass
@dataclassclass Sort: title: str
@dataclassclass Select: row: dict
class Files(pz.App): rows = [{"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730}] sort_by, descending, selected = "Lines", True, None
def update(self, message): match message: case Sort(title): self.descending = not self.descending if title == self.sort_by else False self.sort_by = title case Select(row): self.selected = row
def view(self): return ui.table([ui.Column("File", "name"), ui.Column("Lines", "lines", width=80)], self.rows, sort_by=self.sort_by, descending=self.descending, selected=self.selected, on_sort=Sort, on_row_press=Select)from dataclasses import dataclass
ROWS = ({"name": "app.py", "lines": 512}, {"name": "theme.py", "lines": 730})
@dataclass(frozen=True)class State: sort_by: str = "Lines" descending: bool = True selected: str = ""
def view(state, set_state): key = "name" if state.sort_by == "File" else "lines" rows = sorted(ROWS, key=lambda r: r[key], reverse=state.descending) return ui.table( [ui.Column("File", "name"), ui.Column("Lines", "lines", width=80)], rows, sort_by=state.sort_by, descending=state.descending, selected=next((r for r in rows if r["name"] == state.selected), None), on_sort=lambda t: set_state(sort_by=t, descending=not state.descending if t == state.sort_by else False), on_row_press=lambda row: set_state(selected=row["name"]))Propiedades y API
Sección titulada «Propiedades y API»ui.table
Sección titulada «ui.table»table( columns, rows, *, sort_by=None, descending=False, on_sort=None, on_row_press=None, selected=None, striped=False, row_height=30, height=None, on_row_double_press=None, on_row_context=None, empty=None, theme=None,)Una tabla de datos con encabezado fijo, orden opcional y selección de filas. El orden se hace aquí cuando sort_by nombra una columna: pulsar un encabezado llama a on_sort(título) y tú cambias sort_by/descending en tu estado. Las filas están virtualizadas: solo se construyen las visibles, así que cientos de miles de filas se desplazan con fluidez.
| Propiedad | Por defecto | Descripción |
|---|---|---|
columns |
obligatorio | ui.Column o claves simples. |
rows |
obligatorio | Dicts u objetos. |
sort_by |
None |
Título de la columna por la que se ordena. |
descending |
False |
Orden descendente. |
selected |
None |
La fila a resaltar, o una lista o conjunto de filas (selección múltiple). |
striped |
False |
Filas alternas sombreadas. |
row_height |
30 |
Alto de cada fila. |
height |
None |
Alto: píxeles, "fill", "shrink" o "fill:N" (proporción). |
empty |
None |
Texto o widget que se muestra en lugar de las filas cuando no hay ninguna. |
theme |
None |
Tema a usar en lugar del actual (pyzed.theme.current()). |
Eventos: on_sort, on_row_press, on_row_double_press, on_row_context (eventos).
ui.Column
Sección titulada «ui.Column»@dataclassclass Column(title, key, width='fill', align='start', render=None, sortable=True)Una columna de ui.table. key es una clave de dict, un nombre de atributo o una función de la fila; render (opcional) convierte el valor en un widget. width es "fill", un número o una porción como "fill:2".
| Propiedad | Por defecto | Descripción |
|---|---|---|
title |
obligatorio | Encabezado (y nombre para ordenar). |
key |
obligatorio | Cómo obtener el valor de cada fila. |
width |
"fill" |
Ancho: píxeles, "fill", "shrink" o "fill:N" (proporción). |
align |
"start" |
"start", "center" o "end". |
render |
None |
Función valor → widget. |
sortable |
True |
Si el encabezado se puede pulsar para ordenar. |