El catálogo de tipos
Módulo de ejemplo: hellotypes.
Los tipos de elemento se dividen en dos familias.
Tipos forzosamente de solo lectura en la interfaz
ElementLight (indicador de estado), ElementImg (imagen), ElementVideo (flujo de vídeo), ElementPrg (barra de progreso o spinner) — ninguno de ellos tiene sentido en escritura directa desde un cliente.
Imagen: la convención webroot
Un módulo escribe su archivo en getWebroot() + "/" + getModuleName() + "/...", y da al elemento una URL relativa a esa ubicación:
QDir dir;
dir.mkdir(getWebroot() + "/" + getModuleName());
atomicSaveJpeg(img, getWebroot() + "/" + getModuleName() + "/photo.jpeg");
OST::ImgData data;
data.mUrlJpeg = getModuleName() + "/photo.jpeg";
getEltImg("display", "photo")->setValue(data, true);El controlador solo llama a setWebroot() sobre un módulo después de que su constructor retorne. Todo código que escriba un archivo que dependa del webroot debe por tanto diferirse a la siguiente iteración del bucle de eventos:
QTimer::singleShot(0, this, [this]() {
// getWebroot() est maintenant garanti défini.
});ElementVideo sigue exactamente la misma convención de URL (OST::VideoData::url), para un flujo ya existente por otra parte.
Barra de progreso y spinner: ambos controlados por un valor
ElementPrg tiene dos presentaciones (prgtype: "bar" o "spinner"), pero ambas están determinadas por un valor 0-100 — un spinner no es un indicador de actividad indeterminada, es un anillo cuyo relleno sigue setPrgValue(), exactamente igual que la barra:
getEltPrg("display", "progress")->setPrgValue(42.0, true);
getEltPrg("display", "spinner")->setPrgValue(42.0, true); // oui, le spinner aussi
getEltPrg("display", "spinner")->setDynLabel("En cours...", true);Tipos normalmente editables
ElementBool, ElementString, ElementInt, ElementFloat, ElementDate, ElementTime, ElementDateTime — todos pueden bloquearse en solo lectura a nivel de su propiedad (permission:0), independientemente de cualquier ajuste por elemento (directedit, autoupdate): el control de permiso es el primero que se verifica, antes de todo lo demás.
Restricciones numéricas e información sobre herramienta
Para int/float, cuatro claves JSON opcionales adicionales:
"gain": { "type": "float", "directedit": true, "min": 0, "max": 100, "step": 1, "format": "%.0f", "hint": "Gain capteur" }min/max: límites aceptados.step: incremento del control del lado del cliente.format: formato de visualización (estiloprintf).hint: información sobre herramienta — disponible en todos los tipos de elemento, no solo los numéricos.
Mezclar tipos en una sola propiedad
A diferencia de INDI, donde un vector solo contiene un único tipo de elemento, una propiedad OST puede mezclar libremente tipos distintos:
"editabledata": {
"permission": 2,
"e": {
"bool1": { "type": "bool", "directedit": true },
"string1": { "type": "string", "directedit": true },
"int1": { "type": "int" },
"float1": { "type": "float" },
"date1": { "type": "date", "directedit": true }
}
}directedit:true vs directedit:false
directedit:true: el cliente edita el elemento individualmente y lo envía solo (SV) — aplicado de inmediato.directedit:false: el elemento solo puede modificarse mediante un envío agrupado de toda la propiedad (SA) — todos los elementos editables de la propiedad deben incluirse en ese envío, de lo contrario nada se aplica. En el cliente típico, esto corresponde a dos presentaciones distintas: un control de edición inmediata para cada elementodirectedit:true, y un formulario con un botón “Guardar” que agrupa todos los elementosdirectedit:false.
Esta distinción es independiente del tipo: en el ejemplo anterior, bool1/string1/date1 se editan de inmediato, int1/float1 solo mediante el formulario agrupado.