mte.ui — constructores de especificaciones de formulario¶
Todas las superficies de interfaz de la fase 3 —
ctx.docks.add_panel y
ctx.settings_page.register— toman una
especificación de formulario: un diccionario simple que describe un árbol de
widgets. Construye esas especificaciones con los ayudantes mte.ui.* para no
tener que escribir el JSON a mano.
from mte.ui import (
Column, Row, Group,
Label, Button, Checkbox, LineEdit, NumberSpin, ComboBox, List,
)
Nada de mte.ui habla con Qt ni con PySide: cada ayudante devuelve un diccionario
que sigue el esquema de canal que espera el analizador de formularios en C++ del
anfitrión. Puedes componerlos, empalmar listas o generarlos mediante programación
con toda libertad:
from mte.ui import Column, Row, Label, Button
def make_toolbar(commands):
return Row([Button(text=c["label"], on_click=c["id"])
for c in commands])
form = Column([Label(text="Actions:"),
make_toolbar(my_commands)])
La especificación se valida en el lado del anfitrión; los tipos de control
desconocidos o los campos obligatorios que falten producen un error
InvalidParams que verás en el registro.
Las etiquetas de una especificación de formulario no se traducen
Todo rótulo que pongas en una especificación —títulos de panel, etiquetas de
casillas, encabezados de grupo— se muestra exactamente como lo escribiste, sea
cual sea el idioma de la interfaz. Son datos que tu plugin envía al editor, no
cadenas que el editor pueda buscar en un catálogo de traducción. Si tu plugin
debe hablar más de un idioma, elige tú mismo las cadenas antes de llamar a
register; el idioma actual de la interfaz es
ctx.app_settings.get_string(mte.keys.UI_LANGUAGE) (vacío significa «seguir
al sistema»). Lo mismo vale para el name y la description que tu
plugin.json muestra en Preferencias ▸ Complementos.
Disposiciones¶
Los constructores de disposición toman una lista de diccionarios hijos y los colocan vertical u horizontalmente.
Column(children)¶
Apila los hijos de arriba abajo con un estiramiento al final: los controles se quedan a su altura natural en vez de hincharse para llenar un panel alto.
Row(children)¶
La misma idea, de izquierda a derecha, con un estiramiento horizontal al final.
Group(children, *, title="")¶
Un marco con título (dibujado como QGroupBox) que contiene una pila vertical.
Úsalo para agrupar visualmente controles relacionados:
Group([
Checkbox(id="cs", label="Case sensitive", binds="settings:cs"),
Checkbox(id="ww", label="Whole words", binds="settings:ww"),
], title="Search options")
Las disposiciones se anidan libremente: una Row dentro de una Column dentro de
un Group está bien.
Controles hoja¶
Todas las hojas aceptan los mismos cuatro enlaces compartidos mediante argumentos con nombre:
| Argumento | Significado |
|---|---|
id= |
Identificador estable que usan ctx.ui.get / ctx.ui.set y (de forma implícita) binds. |
binds= |
"settings:<key>" — se guarda automáticamente a través de ctx.settings. |
on_click= |
Identificador de comando que invocar; solo en los botones. |
on_change= |
Identificador de manejador (ctx.docks.on_change(...)); en todos los demás controles. |
Solo las hojas que exponen un «valor» admiten binds y on_change.
Label(*, text="", id=None)¶
Texto estático.
Button(*, text, on_click=None, id=None)¶
Un botón pulsador. Disparar on_click invoca el comando registrado; si quieres
mantener el botón sincronizado con otra cosa, puedes hacer ctx.ui.set sobre su
text.
Checkbox(*, label="", default=False, id=None, binds=None, on_change=None)¶
Control booleano. default es el estado inicial; binds lo anula con el valor
guardado, si existe alguno.
LineEdit(*, placeholder="", default="", id=None, binds=None, on_change=None)¶
Entrada de texto de una sola línea.
NumberSpin(*, default=0, min=None, max=None, step=1, id=None, binds=None, on_change=None)¶
Cuadro numérico con flechas. min y max acotan el intervalo (ambos opcionales;
el QSpinBox subyacente usa su intervalo predeterminado cuando no se fijan).
step es el incremento de las flechas.
Intervalo de int
NumberSpin se apoya en QSpinBox, que almacena un int (de 32 bits). Los
valores fuera de -2_147_483_648 … 2_147_483_647 se saturarán en el límite de
la plataforma.
ComboBox(*, items, default="", id=None, binds=None, on_change=None)¶
Desplegable. items es una lista: cada entrada puede ser una cadena simple o un
objeto como {"value": "cpp", "label": "C++"} (hoy solo se usa value; label
está reservado para un refinamiento futuro).
List(*, items, id=None, on_change=None)¶
Widget de lista con selección única. on_change se dispara con el texto del
elemento recién seleccionado. Sin binds: guarda la selección tú mismo si la
necesitas.
Acceso en tiempo de ejecución¶
Una vez registrado el panel, manéjalo desde cualquier comando:
panel_id = ctx.docks.add_panel(id="my.panel", ..., form=Column([
LineEdit(id="needle"),
Checkbox(id="cs"),
]))
# Read current values
needle = ctx.ui.get(panel_id, "needle")
cs = ctx.ui.get(panel_id, "cs") == "true"
# Write values (does NOT fire on_change)
ctx.ui.set(panel_id, "needle", "hello")
ctx.ui.set(panel_id, "cs", True)
Consulta ctx.ui para la referencia completa.
Guardar valores¶
binds="settings:<key>" es la forma más corta de guardar el valor de un
control:
- Al construir el panel, el widget lee su valor inicial de
ctx.settings.get(key, <default>). - En cada edición del usuario, el widget lo vuelve a escribir mediante
ctx.settings.set(clave, nuevo_valor).
Como los paneles y las páginas de Preferencias comparten ctx.settings, dos
controles con la misma cadena binds se reflejan mutuamente en tiempo real. Así
es como el panel y la página de Preferencias de HelloPython mantienen
sincronizada la casilla «Loud».
Si necesitas guardar algo que el vocabulario no cubre (por ejemplo, la selección
de una List), lee y escribe directamente a través de ctx.settings en una
retrollamada on_change.