Un componente propio
Cuando el mismo grupo de controles aparece una y otra vez (una valoración con estrellas, una tarjeta de usuario, una barra de búsqueda), conviértelo en un componente: lo dibujas una vez, le das propiedades y eventos, y lo colocas donde quieras como un control más. Es la idea de las escenas de Godot y de los widget blueprints de Unreal, y es como las apps grandes se mantienen ordenadas.
| Objetivo | Tiempo | Nivel | Necesitas |
|---|---|---|---|
Un Rating de cinco estrellas que puedes poner en cualquier formulario |
35 minutos | Intermedio · Python | Enlace de datos |
Qué vas a aprender
Sección titulada «Qué vas a aprender»- Crear un componente en la Vista de componente (un
.pzcompy su clase en un.py). - Añadir una propiedad pública (
value) y un estado privado (clicks). - Enlazar las propiedades de los controles a las del componente (
"solid" if value >= 3 else "ghost"). - Escribir métodos y lanzar un evento propio con
self.emit("change", ...). - Probarlo en la ventana de vista previa, ponerlo en un formulario y usarlo desde código Python.
-
Crea el componente. Ctrl+N → Componente, llámalo
ratingy pulsa Crear componente. El diseñador crearating.pzcomp(el dibujo) yrating.py(la claseRating) y los abre en la Vista de componente: un marco de color de acento en lugar de los botones de ventana, y una insignia Componente.
Nueva → Componente: una pieza reutilizable, no una ventana. -
Dibújalo. Sin nada seleccionado, pon el Ancho del componente en 232 y el Alto en 28 (sección Disposición). Coloca cinco Botones en fila llamados
star1…star5, cada uno con el iconostar, sin texto y con varianteghost, y una Etiqueta de texto llamadacaptional final. -
Añade las propiedades. En la sección Properties del panel del componente pulsa Public y crea
value, de tipoint, con valor por defecto3; luegoreadonly, de tipobool. Pulsa Private paraclicks, unintque solo ve el componente. La clase derating.pylos recibe como atributos anotados:value: Annotated[int, pz.Range(0, 5)] = 3readonly: bool = Falseclicks: int = pz.state(0, doc="Times the user picked a rating") -
Enlaza las estrellas. Selecciona
star3, abre Bindings, elige variant y luego Expression…:"solid" if value >= 3 else "ghost"Haz lo mismo con las otras estrellas (cada una con su número) y enlaza
caption.textaf"{value} / 5". Cambiavalueen el panel: las estrellas se encienden en el lienzo.
Los enlaces mantienen los controles al día con las propiedades del componente. -
Añade el evento propio. En Custom events pulsa Event, llámalo
changey descríbelo: A star was picked (event.value is the rating). -
Escribe la lógica. Añade un método
pick(escribe el nombre y pulsa + Method) y haz doble clic en cada estrella para escribir su manejador de clic. En un componente los manejadores son métodos y los controles sonself.<nombre>:def star1_click(self, event):return self.pick(1)def pick(self, stars):"""Lights stars stars and tells the parent."""if self.readonly:return Noneself.value = starsself.clicks += 1return self.emit("change", stars) -
Pruébalo solo. Pulsa F5: el componente se abre en una ventana de vista previa que lista cada evento propio que lanza. Haz clic en las estrellas y mira llegar
change.
F5 sobre un componente: una vista previa con registro de eventos. -
Úsalo en un formulario. Guarda y abre (o crea) un formulario:
Ratingya está en las Herramientas, en su categoría. Pon uno, añade una Etiqueta de texto llamadastatus, selecciona la valoración y, en Eventos, haz doble clic enchange:def rating1_change(form, event):form.status.text = f"You gave it {event.value} stars" # event.value es lo que envió emit()Haz doble clic en un componente colocado para abrirlo en su propia pestaña; los cambios aparecen en cada formulario que lo usa.

Código completo
Sección titulada «Código completo»Los componentes terminados (incluida una ProfileCard que contiene un Rating, y una TeamCard que hereda de
ella) están en examples/designer/components.
"""Rating: a component designed in Pyzed Design.
The layout is in rating.pzcomp; properties, events and logic are below. Use it likeany component: ``Rating(...)`` in a view, or from the designer's toolbox."""
from typing import Annotated
import pyzed as pzfrom pyzed.designer import SceneComponent
class Rating(SceneComponent, scene="rating.pzcomp"): """Five stars the user can click."""
value: Annotated[int, pz.Range(0, 5)] = 3 # How many stars are lit readonly: bool = False clicks: int = pz.state(0, doc="Times the user picked a rating") events = {"change": "A star was picked (event.value is the rating)"}
def star1_click(self, event): return self.pick(1)
def star2_click(self, event): return self.pick(2)
def star3_click(self, event): return self.pick(3)
def star4_click(self, event): return self.pick(4)
def star5_click(self, event): return self.pick(5)
def pick(self, stars): """Lights ``stars`` stars and tells the parent.""" if self.readonly: return None self.value = stars self.clicks += 1 return self.emit("change", stars)"""Event handlers for the Reviews form.
Each function receives the running ``form`` (controls are attributes: ``form.button1.text``)and an ``event`` with ``event.sender``, ``event.name`` and ``event.value``."""
def ada_rated(form, event): """Runs when the card of ada is rated.""" event.sender.score = event.value form.status.text = f"{event.sender.person} now has {event.value} stars"
def grace_rated(form, event): """Runs when the card of grace is rated.""" event.sender.score = event.value form.status.text = f"{event.sender.person} now has {event.value} stars"Ejecuta la vista previa del componente, o el formulario que lo usa:
uv run --with pyzed-ui pyzed run examples/designer/components/rating.pzcomppython3 -m venv .venvsource .venv/bin/activatepython -m pip install pyzed-uipyzed run examples/designer/components/rating.pzcomppy -m venv .venv.venv\Scripts\Activate.ps1python -m pip install pyzed-uipyzed run examples\designer\components\rating.pzcomppython3 -m pyzed run examples/designer/components/rating.pzcomppy -m pyzed run examples\designer\components\rating.pzcompuv run --with pyzed-ui pyzed run examples/designer/components/reviews.pzformpython3 -m venv .venvsource .venv/bin/activatepython -m pip install pyzed-uipyzed run examples/designer/components/reviews.pzformpy -m venv .venv.venv\Scripts\Activate.ps1python -m pip install pyzed-uipyzed run examples\designer\components\reviews.pzformpython3 -m pyzed run examples/designer/components/reviews.pzformpy -m pyzed run examples\designer\components\reviews.pzformEventos de este tutorial
Sección titulada «Eventos de este tutorial»Rating declara un evento propio, change, en events y lo lanza con self.emit("change", stars). El padre lo
escucha con on_change=, y su handler recibe un pz.Event cuyo value es la puntuación. Como todo componente,
Rating lanza además mount y unmount, y acepta los eventos comunes (on_right_click, on_mouse_enter…).
Prueba más eventos
Sección titulada «Prueba más eventos»Un segundo evento propio, que solo se lanza si alguien lo escucha:
class Rating(pz.Component): value: int = 0 events = { "change": "Se eligió una estrella (event.value es la puntuación).", "clear": "Se borró la puntuación con un clic derecho.", # nuevo }
def render(self): stars = pz.row([...]) # como en el tutorial if self.handles("clear"): # solo si el padre pasó on_clear stars = stars.on(right_click=lambda: self.emit("clear")) return stars
# El padre, en su view:Rating(value=self.stars, on_change=lambda e: setattr(self, "stars", e.value), on_clear=lambda: setattr(self, "stars", 0), # sin argumentos: se llama sin nada on_mount=lambda: print("la puntuación está en pantalla"))Más en crear tus propios eventos.
Siguiente
Sección titulada «Siguiente»- Diseñador de componentes: cada sección del panel del componente, tipos de propiedad, anidación, componentes adaptables y herencia.
- Tareas en segundo plano.