13.1.13. Uređivač postavki#

Mnoge aplikacije za kameru trebaju nekoliko postavki koje neprogramer može promijeniti – prag, način rada, Wi-Fi lozinku – bez diranja skripte. OpenMV Cam Settings Editor je alat IDE-a za to: JSON datoteka opisuje kontrole, uređivač taj opis pretvara u obrazac, a vaša skripta čita spremljene vrijednosti pomoću json.load(). Datoteka je istovremeno i konfiguracija i definicija vlastitog uređivača, pa ista konfiguracija koja pohranjuje vrijednosti ujedno raspoređuje i GUI za njihovo uređivanje.

Podizbornik Tools → OpenMV Cam Settings Editor sadrži njegove tri radnje.

  • Open OpenMV Cam Settings Config File čita konfiguraciju s pogona povezane kamere i otvara je u uređivaču; spremanje je zapisuje natrag na kameru.

  • Open Config File čini isto za .json datoteku na vašem računalu, radi pripreme konfiguracije izvan mreže.

  • Create Default Config piše početnu konfiguraciju na disk i otvara je – primjer koji iskorištava svaku vrstu kontrole, spreman za svođenje na postavke koje vaša vlastita aplikacija treba.

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

Uređivač postavki s otvorenom zadanom konfiguracijom – kontrole JSON datoteke raspoređene kao obrazac (kartice, klizači, padajući izbornici, potvrdni okviri), sa Save i Cancel na dnu.#

13.1.13.1. Anatomija konfiguracijske datoteke#

Konfiguracijska datoteka je jedan JSON objekt s dva ključa:

  • title (niz znakova, opcionalno) – naslov prozora uređivača. Zadano OpenMV Cam Settings Editor.

  • controls (polje, obavezno) – popis objekata kontrola koje uređivač prikazuje, redom, kao retke obrasca. To je cijeli GUI.

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

Svaki unos u controls je jedna kontrola – tekstualno polje, broj, potvrdni okvir, padajući izbornik, klizač, grupa, traka kartica, statična oznaka i tako dalje. Njegov type odabire widget; ostatak objekta ga konfigurira. Svi ključevi koje uređivač ne prepozna ostaju netaknuti pri spremanju datoteke, pa u datoteci uz kontrole možete zadržati vlastite metapodatke.

13.1.13.2. Ključevi koje dijeli svaka kontrola#

Svaki objekt kontrole prihvaća ove ključeve, bez obzira na njegov type:

  • type (niz znakova, obavezno) – koji widget izgraditi, npr. "slider" ili "combobox". Nedostajući ili neprepoznat type prikazuje onemogućeni rezervirani element Unknown control umjesto da poništi cijelu datoteku, pa vas tipfeler košta jedne kontrole, a ne obrasca.

  • name (niz znakova) – identifikator za vašu upotrebu. Uređivač ga nikada ne čita; samo ga čuva. Dajte svakoj kontroli jedinstveni name i vaša skripta ga koristi za pronalaženje spremljene vrijednosti te kontrole.

  • label (niz znakova) – tekst prikazan pored ili na kontroli. Za većinu kontrola ovo je obogaćeni tekst – HTML oznake i <a href> poveznice funkcioniraju.

  • tooltip (niz znakova) – tekst koji se prikazuje pri prelasku mišem preko kontrole.

  • enabled (boolean, zadano true) – postavite na false da bi se kontrola prikazala zasivljeno i samo za čitanje.

Kontrole spremnika (group, tabs) koriste title umjesto label za svoj naslov, a tabs prihvaća svoj tooltip po kartici; razlike su navedene na stranici svake kontrole.

13.1.13.3. Spremanje i čitanje vrijednosti#

Kontrola koja sadrži vrijednost – potvrdni okvir, klizač, tekstualno polje – nosi je u ključu value. Kada kliknete Spremi, uređivač piše trenutnu value svake kontrole izravno natrag u taj isti objekt kontrole, na mjestu, i ponovno piše datoteku. Datoteka zadržava svoju strukturu: ništa se ne pomiče, mijenjaju se samo ključevi value. Ne postoji zasebna plosnata mapa name na vrijednost – vrijednosti žive unutar kontrola, upravo tamo gdje su definirane.

Zato je raspored važan za vašu skriptu. Polja controls i tabs zadržavaju redoslijed kojim ste ih izgradili, pa se datoteka ne može indeksirati po imenu kao rječnik – config["controls"]["threshold"] ne funkcionira. Ovaj mali pomoćnik premošćuje jaz: dajte mu put imena do vrijednosti koju želite i on prolazi stablo umjesto vas.

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

Svaki korak u putu je name kontrole ili title kartice (kartica nema vlastiti name, iako ga možete dodati i on se čuva). Traka kartica i svaka group koju niste imenovali su prozirni – find prolazi kroz njih – pa navodite samo kartice i kontrole koje ste označili, blisko ugniježđenom config[...][...] pretraživanju. Imenovana group je korak za sebe, pa find može vratiti i vrijednost njezinog potvrdnog okvira. Dajte svakoj kontroli jedinstveni name kako put nikada ne bi bio dvosmislen. Potpuni primjer čita vrijednosti iz ugniježđenog demonstracijskog rasporeda.

Budući da je konfiguracija običan JSON, ništa u vašoj skripti ne ovisi o uređivaču – uređivač samo piše datoteku koju vaša skripta već čita. Uređaj može nositi svoju konfiguraciju i pristupačan način za njezinu promjenu, dok skripta ostaje običan čitač vrijednosti.

Jedna vrsta kontrole nameće svoj unos pri spremanju: lineedit s mask ili regex ne dopušta uređivaču spremanje dok je njegov tekst nevaljan ili nepotpun i imenuje polja koja treba ispraviti. Svaka druga kontrola ograničava unos dok uređujete – klizač ne može napustiti svoj raspon, spinbox se ograničava na svoje granice – pa je spremljena datoteka uvijek valjana.

13.1.13.4. Referenca konfiguracijske datoteke#

Vrste kontrola dokumentirane su na donjim stranicama, grupirane prema onome što rade.