13.1.13. A beállításszerkesztő#
Sok kameraalkalmazásnak szüksége van néhány olyan beállításra, amelyet egy nem programozó is módosíthat – egy küszöbérték, egy mód, egy Wi-Fi-jelszó – a szkript érintése nélkül. Az OpenMV Cam Settings Editor az IDE erre szolgáló eszköze: egy JSON-fájl írja le a vezérlőelemeket, a szerkesztő ezt a leírást űrlappá alakítja, a szkripted pedig a json.load() segítségével olvassa vissza a mentett értékeket. A fájl egyszerre a konfiguráció és a saját szerkesztőjének a definíciója, így ugyanaz a konfiguráció, amely tárolja az értékeket, rendezi el a szerkesztésükre szolgáló grafikus felületet is.
A Tools → OpenMV Cam Settings Editor almenü tartalmazza a három műveletét.
Az Open OpenMV Cam Settings Config File beolvassa a konfigurációt a csatlakoztatott kamera meghajtójáról, és megnyitja a szerkesztőben; mentéskor visszaírja a kamerára.
Az Open Config File ugyanezt teszi egy, a számítógépeden lévő
.jsonfájllal, egy konfiguráció offline előkészítéséhez.A Create Default Config egy kezdő konfigurációt ír a lemezre és megnyitja azt – egy példa, amely minden vezérlőtípust gyakorol, készen arra, hogy leegyszerűsítsd a saját alkalmazásod által igényelt beállításokra.

A beállításszerkesztő a megnyitott alapértelmezett konfigurációval – a JSON fájl vezérlőelemei űrlapként elrendezve (fülek, csúszkák, legördülő listák, jelölőnégyzetek), a Save és Cancel gombokkal az alján.#
13.1.13.1. Egy konfigurációs fájl felépítése#
Egy konfigurációs fájl egyetlen JSON objektum két kulccsal:
title (string, opcionális) – a szerkesztőablak címe. Alapértelmezés szerint
OpenMV Cam Settings Editor.controls (array, kötelező) – a vezérlőobjektumok listája, amelyeket a szerkesztő sorrendben, egy űrlap soraiként jelenít meg. Ez a teljes grafikus felület.
{
"title": "Camera Settings",
"controls": [
{ "type": "slider", "name": "threshold", "label": "Threshold", "value": 50 },
{ "type": "checkbox", "name": "draw_overlays", "label": "Draw Overlays", "value": true }
]
}
A controls minden egyes eleme egy vezérlő – egy szövegmező, egy szám, egy jelölőnégyzet, egy legördülő menü, egy csúszka, egy csoport, egy fülsáv, egy statikus felirat és így tovább. A type mezője választja ki a widgetet; az objektum többi része konfigurálja azt. A szerkesztő által nem felismert kulcsok érintetlenül maradnak a fájl mentésekor, így a vezérlők mellett saját metaadatokat is tárolhatsz a fájlban.
13.1.13.3. Értékek mentése és olvasása#
Egy értéket hordozó vezérlő – egy jelölőnégyzet, egy csúszka, egy szövegmező – azt egy value kulcsban hordozza. Amikor a Mentés gombra kattintasz, a szerkesztő minden vezérlő aktuális value értékét helyben, ugyanabba a vezérlőobjektumba írja vissza, és újraírja a fájlt. A fájl megőrzi a szerkezetét: semmi sem mozdul el, csak a value kulcsok változnak. Nincs külön, lapos name-érték leképezés – az értékek a vezérlőkön belül élnek, pontosan ott, ahol definiálva vannak.
Ezért fontos az elrendezés a szkripted számára. A controls és tabs tömbök megtartják azt a sorrendet, amelyben felépítetted őket, így a fájl nem indexelhető név szerint, mint egy szótár – a config["controls"]["threshold"] nem működik. Ez a kis segédfüggvény áthidalja a szakadékot: add meg neki a nevek útvonalát egészen a kívánt értékig, és bejárja helyetted a fát.
import json
def find(node, *path):
"""Return the control at a path of names; read its value with
["value"]. The tab strip and any unnamed group are transparent,
so you list only the tabs and controls you gave a name."""
for key in path:
match = _child(node, key)
if match is None:
raise KeyError(key)
node = match
return node
def _child(node, key):
for member in node.get("controls", []) + node.get("tabs", []):
if member.get("name") == key or member.get("title") == key:
return member
if "name" not in member and ("controls" in member or "tabs" in member):
match = _child(member, key) # see through an unnamed group / the tab strip
if match is not None:
return match
return None
with open("config.json") as file:
config = json.load(file)
threshold = find(config, "threshold")["value"]
Az útvonal minden lépése egy vezérlő name mezője vagy egy fül title mezője (egy fülnek nincs saját name mezője, bár hozzáadhatsz egyet, és az megőrződik). A fülsáv és bármely olyan group, amelynek nem adtál nevet, átlátszó – a find végiglép rajtuk –, így csak azokat a füleket és vezérlőket sorolod fel, amelyeket feliratoztál, közel egy beágyazott config[...][...] kereséshez. Egy elnevezett group saját lépés, így a find a jelölőnégyzetének értékét is visszaadhatja. Adj minden vezérlőnek egyedi name értéket, hogy egy útvonal soha ne legyen kétértelmű. Az Teljes példa a beágyazott bemutató-elrendezésből olvassa ki az értékeket.
Mivel a konfiguráció egyszerű JSON, a szkriptedben semmi sem függ a szerkesztőtől – a szerkesztő csak azt a fájlt írja, amelyet a szkripted amúgy is beolvas. Egy eszköz hordozhatja a konfigurációját és egy barátságos módot annak megváltoztatására, miközben a szkript az értékek egyszerű olvasója marad.
Egyetlen vezérlőtípus kényszeríti ki a bevitelét Mentéskor: egy mask vagy regex értékkel rendelkező lineedit megtagadja, hogy a szerkesztő mentsen, amíg a szövege érvénytelen vagy hiányos, és megnevezi a javítandó mezőket. Minden más vezérlő szerkesztés közben korlátozza a bevitelt – egy csúszka nem léphet ki a tartományából, egy spinbox a határaihoz igazodik –, így egy mentett fájl mindig érvényes.
13.1.13.4. Konfigurációs fájl referencia#
A vezérlőtípusok az alábbi oldalakon vannak dokumentálva, aszerint csoportosítva, hogy mit csinálnak.