Ir al contenido

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 →

TablaTabla
  • 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 pz
from 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,
)
Tabla: SimpleTabla: Simple
Simple
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)
Tabla: striped=TrueTabla: striped=True
striped=True
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}], striped=True), width=320)
Tabla: selected=Tabla: selected=
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)
Tabla: sort_by=, descending=TrueTabla: sort_by=, descending=True
sort_by=, descending=True
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}], sort_by="Lines", descending=True,
on_sort=on_sort), width=320)
Tabla: row_height=24Tabla: row_height=24
row_height=24
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}], row_height=24), width=320)
Tabla: render=Tabla: render=
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)
Tabla: key=lambdaTabla: key=lambda
key=lambda
Có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)

on_row_double_press(fila) abre una fila y on_row_context(fila) muestra un menú contextual.

Tabla: Selección múltipleTabla: Selección múltiple
Selección múltiple
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)
Tabla: empty=Tabla: empty=
empty=
Código
ui.table(["name", "size"], [], empty="No files yet", height=100)

render recibe el valor y devuelve un widget, aquí una insignia.

Tabla: Celdas personalizadasTabla: Celdas personalizadas

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().

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
)
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).

Referencia completa →

@dataclass
class 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.

Referencia completa →