13.1.13. Asetuseditori#

Monet kamerasovellukset tarvitsevat kourallisen asetuksia, joita ei-ohjelmoija voi muuttaa – kynnysarvo, tila, Wi-Fi-salasana – koskematta skriptiin. OpenMV Cam Settings Editor on IDE:n työkalu siihen: JSON-tiedosto kuvaa säätimet, editori muuntaa tuon kuvauksen lomakkeeksi, ja skriptisi lukee tallennetut arvot takaisin funktiolla json.load(). Tiedosto on sekä määritys että oman editorinsa määrittely, joten sama määritys, joka tallentaa arvot, myös asettelee niiden muokkaamiseen tarkoitetun käyttöliittymän.

Tools → OpenMV Cam Settings Editor -alivalikko sisältää sen kolme toimintoa.

  • Open OpenMV Cam Settings Config File lukee määrityksen yhdistetyn kameran asemasta ja avaa sen editorissa; tallentaminen kirjoittaa sen takaisin kameraan.

  • Open Config File tekee saman tietokoneellasi olevalle .json-tiedostolle, määrityksen valmisteluun offline-tilassa.

  • Create Default Config kirjoittaa aloitusmäärityksen levylle ja avaa sen – esimerkin, joka käyttää jokaista säädintyyppiä ja on valmis karsittavaksi niihin asetuksiin, joita oma sovelluksesi tarvitsee.

The OpenMV Cam Settings Editor showing the default demo configuration -- Camera, Processing, Network, and System tabs, with the Camera tab's exposure and gain sliders, resolution and pixel-format dropdowns, mirror and flip checkboxes, and a digital-zoom slider, above the Save and Cancel buttons

Asetuseditori oletuskokoonpano avattuna – JSON-tiedoston säätimet lomakkeeksi aseteltuina (välilehdet, liukusäätimet, pudotusvalikot, valintaruudut), Save ja Cancel alareunassa.#

13.1.13.1. Määritystiedoston rakenne#

Määritystiedosto on yksittäinen JSON-objekti, jolla on kaksi avainta:

  • title (merkkijono, valinnainen) – editori-ikkunan otsikko. Oletuksena OpenMV Cam Settings Editor.

  • controls (taulukko, pakollinen) – luettelo säädinobjekteista, jotka editori piirtää järjestyksessä lomakkeen riveinä. Tämä on koko graafinen käyttöliittymä.

{
  "title": "Camera Settings",
  "controls": [
    { "type": "slider", "name": "threshold", "label": "Threshold", "value": 50 },
    { "type": "checkbox", "name": "draw_overlays", "label": "Draw Overlays", "value": true }
  ]
}

Jokainen controls -taulukon kohta on yksi säädin – tekstikenttä, luku, valintaruutu, pudotusvalikko, liukusäädin, ryhmä, välilehtipalkki, staattinen nimike ja niin edelleen. Sen type valitsee komponentin; objektin loppuosa määrittää sen. Kaikki avaimet, joita editori ei tunnista, jätetään koskematta tiedostoa tallennettaessa, joten voit säilyttää tiedostossa omat metatietosi säätimien rinnalla.

13.1.13.2. Avaimet, jotka jokainen säädin jakaa#

Jokainen säädinobjekti hyväksyy nämä avaimet riippumatta sen type-arvosta:

  • type (merkkijono, pakollinen) – mikä komponentti rakennetaan, esim. "slider" tai "combobox". Puuttuva tai tunnistamaton type piirtää käytöstä poistetun Unknown control -paikanpitäjän sen sijaan, että koko tiedosto epäonnistuisi, joten kirjoitusvirhe maksaa yhden säätimen, ei koko lomaketta.

  • name (merkkijono) – tunniste sinun käyttöösi. Editori ei koskaan lue sitä; se vain säilyttää sen. Anna jokaiselle säätimelle yksilöllinen name, niin skriptisi käyttää sitä löytääkseen kyseisen säätimen tallennetun arvon.

  • label (merkkijono) – säätimen vieressä tai päällä näytettävä teksti. Useimmilla säätimillä tämä on muotoiltua tekstiä – HTML-tunnisteet ja <a href> -linkit toimivat.

  • tooltip (merkkijono) – säätimen osoitinvihje.

  • enabled (totuusarvo, oletus true) – aseta arvoon false näyttääksesi säätimen harmaana ja vain luettavana.

Säiliösäätimet (group, tabs) käyttävät otsikkonaan title-avainta label-avaimen sijaan, ja tabs ottaa osoitinvihjeensä välilehtikohtaisesti; erot on huomautettu kunkin säätimen sivulla.

13.1.13.3. Arvojen tallentaminen ja lukeminen#

Säädin, joka sisältää arvon – valintaruutu, liukusäädin, tekstikenttä – kantaa sitä value -avaimessa. Kun napsautat Tallenna, editori kirjoittaa kunkin säätimen nykyisen value-arvon suoraan takaisin samaan säädinobjektiin paikoilleen ja kirjoittaa tiedoston uudelleen. Tiedosto säilyttää rakenteensa: mikään ei siirry, vain value -avaimet muuttuvat. Erillistä litteää name-arvo-yhdistystä ei ole – arvot elävät säätimien sisällä, juuri siellä missä ne on määritelty.

Siksi asettelulla on merkitystä skriptillesi. controls- ja tabs -taulukot säilyttävät sen järjestyksen, jossa ne rakensit, joten tiedostoa ei voi indeksoida nimellä sanakirjan tavoin – config["controls"]["threshold"] ei toimi. Tämä pieni apufunktio kuroo umpeen tämän kuilun: anna sille nimipolku haluamaasi arvoon asti, ja se kulkee puun läpi puolestasi.

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"]

Jokainen askel polulla on säätimen name tai välilehden title (välilehdellä ei ole omaa name-arvoa, vaikka voit lisätä sellaisen ja se säilytetään). Välilehtipalkki ja mikä tahansa nimeämättä jättämäsi group ovat läpinäkyviä – find etenee niiden läpi – joten luettelet vain nimeämäsi välilehdet ja säätimet, lähellä sisäkkäistä config[...][...] -hakua. Nimetty group on oma askeleensa, joten find voi myös palauttaa sen valintaruudun arvon. Anna jokaiselle säätimelle yksilöllinen name, jotta polku ei koskaan ole moniselitteinen. Täydellinen esimerkki lukee arvoja sisäkkäisestä esittelyasettelusta.

Koska määritys on tavallista JSON-muotoa, mikään skriptissäsi ei riipu editorista – editori vain kirjoittaa tiedoston, jonka skriptisi jo lukee. Laite voi kantaa mukanaan määrityksensä ja helppokäyttöisen tavan muuttaa sitä, kun taas skripti pysyy pelkkänä arvojen lukijana.

Yksi säädintyyppi pakottaa syötteensä tallennettaessa: lineedit, jolla on mask tai regex, ei salli editorin tallentaa, kun sen teksti on virheellinen tai epätäydellinen, ja nimeää korjattavat kentät. Jokainen muu säädin rajoittaa syötettä muokkauksen aikana – liukusäädin ei voi ylittää aluettaan, spinbox rajautuu rajoihinsa – joten tallennettu tiedosto on aina kelvollinen.

13.1.13.4. Määritystiedoston viite#

Säädintyypit on dokumentoitu alla olevilla sivuilla, ryhmiteltynä sen mukaan, mitä ne tekevät.