Lista virtual
Una lista con scroll para miles o millones de elementos. Solo se construyen las filas visibles: render(elemento) se llama cuando un elemento entra en la vista, así que la lista cuesta lo mismo sea cual sea su longitud. Todas las filas tienen la misma item_height. pz.virtual_column es la pieza de debajo (filas por índice, dentro de cualquier scrollable), y la Tabla también la usa para sus filas.
ui.virtual_list · Categoría: Listas y menús · Referencia completa →


files = [f"src/module_{i:06}.py" for i in range(1_000_000)]pz.container(ui.virtual_list( files, lambda f: ui.list_item(f, icon="file-code", selected=f.endswith("02.py")), height=240,), width=420)Cuándo usarlo
Sección titulada «Cuándo usarlo»- Para logs, resultados de búsqueda, listas de archivos o cualquier lista que pueda pasar de unos cientos de filas.
- Para listas cortas, una
pz.columnde Filas es más sencilla.
import pyzed as pzfrom pyzed import ui
class Logs(pz.App): def __init__(self): self.lines = [f"[{i:06}] request handled" for i in range(500_000)]
def view(self): return ui.virtual_list(self.lines, lambda line: pz.text(line, font="mono", size=12), item_height=20, id="logs")Variantes
Sección titulada «Variantes»Opciones
Sección titulada «Opciones»

Código
pz.container(ui.virtual_list([f"row {i:,}" for i in range(1_000_000)], lambda r: ui.list_item(r, icon="file"), height=150), width=260)

item_height=20Código
pz.container(ui.virtual_list([f"[{i:06}] request handled" for i in range(100_000)], lambda line: pz.text(line, font="mono", size=12), item_height=20, height=150), width=260)

spacing=6Código
pz.container(ui.virtual_list(list(range(10_000)), lambda i: ui.card(ui.label(f"Card {i}"), padding=8), item_height=40, spacing=6, height=150), width=260)Ejemplos
Sección titulada «Ejemplos»Filas por índice
Sección titulada «Filas por índice»pz.virtual_column(count, item, item_height=...) llama a item(índice), útil cuando las filas salen de un array, un cursor de base de datos o un cálculo. Se desplaza como cualquier scrollable: la fila i empieza en i * (item_height + spacing).


pz.container(pz.scrollable( pz.virtual_column(10_000_000, lambda i: pz.text(f"{i:>10,} {i * i:>22,}", font="mono", size=12), item_height=22), height=150,), width=420)Eventos
Sección titulada «Eventos»Lista virtual tiene 1 evento 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_scroll |
(info) |
Callable que recibe el viewport del scroll, como en pz.scrollable. |
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 Logs(pz.App): def __init__(self): self.lines = [f"[{i:06}] request handled" for i in range(100_000)] self.top = 0
def scrolled(self, info): # on_scroll: offsets and sizes of the viewport self.top = int(info["y"] // 20)
def view(self): return pz.column([ ui.label(f"Line {self.top + 1} of {len(self.lines)}"), ui.virtual_list(self.lines, lambda line: pz.text(line, font="mono", size=12), item_height=20, height=200, on_scroll=self.scrolled), ], spacing=6)from dataclasses import dataclass
@dataclassclass Scrolled: info: dict
class Logs(pz.App): lines = [f"[{i:06}] request handled" for i in range(100_000)] top = 0
def update(self, message): match message: case Scrolled(info): self.top = int(info["y"] // 20)
def view(self): return ui.virtual_list(self.lines, lambda line: pz.text(line, size=12), item_height=20, height=200, on_scroll=Scrolled)from dataclasses import dataclass
LINES = [f"[{i:06}] request handled" for i in range(100_000)]
@dataclass(frozen=True)class State: top: int = 0
def view(state, set_state): return pz.column([ ui.label(f"Line {state.top + 1}"), ui.virtual_list(LINES, lambda line: pz.text(line, size=12), item_height=20, height=200, on_scroll=lambda info: set_state(top=int(info["y"] // 20))), ], spacing=6)Consejos
Sección titulada «Consejos»Propiedades y API
Sección titulada «Propiedades y API»ui.virtual_list
Sección titulada «ui.virtual_list»virtual_list( items, render, *, item_height=26, spacing=0, width='fill', height='fill', padding=None, overscan=4, id=None, on_scroll=None, theme=None,)Una lista con scroll que solo construye las filas visibles, para miles o millones de elementos. render(elemento) devuelve el widget de un elemento y se llama cuando entra en la vista. Todas las filas tienen la misma altura.
| Propiedad | Por defecto | Descripción |
|---|---|---|
items |
obligatorio | Los elementos: una lista o cualquier secuencia (otros iterables se convierten en lista). |
render |
obligatorio | Función que recibe un elemento y devuelve su widget. |
item_height |
26 |
Altura de cada fila, en píxeles. |
spacing |
0 |
Separación entre hijos, en píxeles. |
width |
"fill" |
Ancho: píxeles, "fill", "shrink" o "fill:N" (proporción). |
height |
"fill" |
Alto: píxeles, "fill", "shrink" o "fill:N" (proporción). |
padding |
None |
Relleno interior: 8, (vertical, horizontal) o (arriba, derecha, abajo, izquierda). |
overscan |
4 |
Filas extra construidas por encima y por debajo de las visibles. |
id |
None |
Identificador estable para enfocarlo o desplazarlo con un Command. |
theme |
None |
Tema a usar en lugar del actual (pyzed.theme.current()). |
Eventos: on_scroll (eventos).
pz.virtual_column
Sección titulada «pz.virtual_column»virtual_column(count, item, *, item_height, spacing=0.0, overscan=4, width=None)Una columna de count filas de la misma altura que solo construye las filas visibles: item(índice) se llama cuando la fila entra en la vista, y las que salen se descartan. Una columna de un millón de filas cuesta lo mismo que una de cincuenta. Ponla dentro de un scrollable (se virtualiza contra el área visible del más cercano, o de la ventana).
| Propiedad | Por defecto | Descripción |
|---|---|---|
count |
obligatorio | Número de filas. |
item |
obligatorio | Función que recibe el índice de una fila y devuelve su widget. |
item_height |
obligatorio | Altura de cada fila, en píxeles. |
spacing |
0.0 |
Espacio entre filas, en píxeles. |
overscan |
4 |
Filas extra construidas por encima y por debajo de las visibles, para que el scroll rápido no deje huecos. |
width |
None |
Ancho: píxeles, "fill", "shrink" o "fill:N" (proporción). |