13.1.13. Редактор настроек#
Многим приложениям для камеры нужна горстка настроек, которые непрограммист может изменить – порог, режим, пароль Wi-Fi – не касаясь скрипта. OpenMV Cam Settings Editor — инструмент IDE для этого: файл JSON описывает элементы управления, редактор превращает это описание в форму, а ваш скрипт считывает сохранённые значения обратно с помощью json.load(). Файл является одновременно и конфигурацией, и определением собственного редактора, поэтому та же конфигурация, что хранит значения, также формирует GUI для их редактирования.
Подменю Tools → OpenMV Cam Settings Editor содержит три его действия.
Open OpenMV Cam Settings Config File считывает конфигурацию с диска подключённой камеры и открывает её в редакторе; сохранение записывает её обратно на камеру.
Open Config File делает то же самое для файла
.jsonна вашем компьютере, для подготовки конфигурации в автономном режиме.Create Default Config записывает стартовую конфигурацию на диск и открывает её – пример, задействующий каждый тип элемента управления, готовый к сокращению до настроек, которые нужны вашему собственному приложению.

Редактор настроек с открытой конфигурацией по умолчанию – элементы управления из JSON-файла представлены в виде формы (вкладки, ползунки, раскрывающиеся списки, флажки), с кнопками Save и Cancel внизу.#
13.1.13.1. Структура файла конфигурации#
Файл конфигурации – это единый JSON-объект с двумя ключами:
title (строка, необязательный) – заголовок окна редактора. По умолчанию
OpenMV Cam Settings Editor.controls (массив, обязательный) – список объектов элементов управления, которые редактор отображает по порядку в виде строк формы. Это весь графический интерфейс.
{
"title": "Camera Settings",
"controls": [
{ "type": "slider", "name": "threshold", "label": "Threshold", "value": 50 },
{ "type": "checkbox", "name": "draw_overlays", "label": "Draw Overlays", "value": true }
]
}
Каждая запись в controls – это один элемент управления: текстовое поле, число, флажок, выпадающий список, ползунок, группа, полоса вкладок, статическая метка и так далее. Его type выбирает виджет; остальная часть объекта настраивает его. Любые ключи, которые редактор не распознаёт, остаются нетронутыми при сохранении файла, поэтому вы можете хранить в файле собственные метаданные рядом с элементами управления.
13.1.13.3. Сохранение и чтение значений#
Элемент управления, который хранит значение – флажок, ползунок, текстовое поле – несёт его в ключе value. Когда вы нажимаете Save, редактор записывает текущее value каждого элемента управления прямо обратно в тот же объект элемента управления, на месте, и перезаписывает файл. Файл сохраняет свою структуру: ничего не перемещается, меняются только ключи value. Нет отдельного плоского отображения name в значение – значения живут внутри элементов управления, прямо там, где они определены.
Вот почему компоновка важна для вашего сценария. Массивы controls и tabs сохраняют порядок, в котором вы их построили, поэтому к файлу нельзя обращаться по имени, как к словарю – config["controls"]["threshold"] не работает. Эта небольшая вспомогательная функция устраняет разрыв: передайте ей путь из имён до нужного вам значения, и она сама обойдёт дерево.
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"]
Каждый шаг в пути – это name элемента управления или title вкладки (вкладка не имеет собственного name, хотя вы можете его добавить, и оно будет сохранено). Полоса вкладок и любая group, которой вы не дали имени, прозрачны – find проходит сквозь них – поэтому вы перечисляете только вкладки и элементы управления, которым вы дали метки, близко к вложенному поиску config[...][...]. Именованная group является отдельным шагом, поэтому find может также вернуть значение её флажка. Дайте каждому элементу управления уникальное name, чтобы путь никогда не был неоднозначным. Полный пример читает значения из вложенной демонстрационной компоновки.
Поскольку конфигурация – это обычный JSON, ничто в вашем сценарии не зависит от редактора – редактор лишь записывает файл, который ваш сценарий уже читает. Устройство может нести свою конфигурацию и удобный способ её изменения, в то время как сценарий остаётся простым читателем значений.
Один тип элемента управления проверяет свой ввод при сохранении: lineedit с mask или regex не позволяет редактору сохранить, пока его текст недопустим или неполон, и называет поля, которые нужно исправить. Все остальные элементы управления ограничивают ввод по мере редактирования – ползунок не может выйти за свой диапазон, spinbox зажимается в своих границах – поэтому сохранённый файл всегда допустим.
13.1.13.4. Справочник по файлу конфигурации#
Типы элементов управления описаны на страницах ниже, сгруппированные по тому, что они делают.