架构与 JSON 驱动的 QML 页面生成机制)
无人机智能硬件【免费下载链接】qgroundcontrolCross-platform ground control station for drones (Android, iOS, Mac OS, Linux, Windows)项目地址https://gitcode.com/gh_mirrors/qg/qgroundcontrol点击查看免费下载QGroundControl 的应用设置界面Settings View是一个JSON 定义 Python 生成器 QML 渲染的混合体系绝大多数设置页由*.SettingsUI.json与*.SettingsGroup.json在构建期自动生成 QML少数复杂页面帮助、日志、调试类仍为手写 QML。本文以 docs/en/qgc-dev-guide/views/settings.md 及其姊妹篇 docs/en/qgc-dev-guide/views/settings_generation.md 为骨架结合仓库内真实源码与配置完整讲解设置视图的组成、生成流水线、JSON Schema 各字段语义以及如何新增一个设置项、新增一个设置页、甚至为自定义构建QGC_CUSTOM_DIR覆盖整个设置体系。读完本文你将具备直接上手修改 QGC 设置 UI 的完整实战能力。设置视图的组成生成 QML 与手写 QML 的混合QGC 的应用设置 UI 并非单一文件而是由生成的 QML与手写 QML两类来源拼接而成设置容器/侧边栏由 src/QmlControls/AppSettings.qml 实现。该文件负责侧边栏页面列表、可展开的 section、顶部搜索框以及仅在有可用页面时才显示分隔线等交互逻辑文件内_pageAvailable、_dividerVisible、_searchQuery等函数即对应这些行为。绝大多数设置内容页由 src/AppSettings/pages 目录下的 JSON 定义在构建期生成例如General.SettingsUI.json、FlyView.SettingsUI.json、Video.SettingsUI.json等。少量手写页面仍以url形式直接被引用不经过生成器例如 HelpHelpSettings.qml、LoggingAppLogging.qml、DebugDebugWindow.qml等。这种混合设计的直接证据见 src/AppSettings/CMakeLists.txtqt_add_qml_module的QML_FILES同时包含生成输出${_generated_qml}与一长串手写文件AppLogging.qml、BluetoothSettings.qml、SerialSettings.qml、TcpSettings.qml、UdpSettings.qml、NtripConnectionSettings.qml等。生成流水线的运行时数据栈从底层事实数据到最终渲染页面设置体系共分 6 层这也是理解整个机制的主线Fact 元数据src/Settings/*.SettingsGroup.json—— 定义每个设置项Fact的类型、标签、枚举、范围、默认值与关键词。例如 src/Settings/App.SettingsGroup.json 中的preferredFirmwareClass为uint32enumStrings为No preference,ArduPilot,PX4 ProenumValues为0,3,12默认值0。Settings Fact 访问器src/Settings/*Settings.h/.cc—— 每个设置组对应一个SettingsGroup子类通过DEFINE_SETTINGFACT(factName)/DECLARE_SETTINGSFACT宏把 JSON 元数据暴露为 C Fact 对象。设置 UI 页面定义src/AppSettings/pages/*.SettingsUI.json—— 描述每个页面的分组、控件布局与可见/可用条件。页面列表src/AppSettings/pages/SettingsPages.json—— 决定侧边栏中页面的顺序、图标、是否生成、可见性表达式与分隔线。Python 生成器tools/generators/settings_qml—— 读取 3、4 两层 JSON 与第 1 层元数据输出页面 QML。生成的 QML被 src/QmlControls/AppSettings.qml 加载编译进QGroundControl.AppSettingsQML 模块。构建期 CMake 运行生成器把生成的 QML 放入构建树再统一编译进上述 QML 模块参见 src/AppSettings/CMakeLists.txt 中的qgc_add_qml_codegen与qt_add_qml_module(URI QGroundControl.AppSettings ...)。CMake 如何接入生成器生成环节在 src/AppSettings/CMakeLists.txt 中配置自定义命令执行python -m tools.generators.settings_qml.generate_pages --output-dir build/generated输入src/AppSettings/pages/*.json页面定义src/Settings/*.SettingsGroup.json设置元数据输出各页面 QML如GeneralSettings.qml、FlyViewSettings.qmlSettingsPagesModel.qml侧边栏模型生成器入口为 tools/generators/settings_qml/generate_pages.py核心逻辑在 tools/generators/settings_qml/page_generator.py。从generate_pages.py的源码可以确认完整的命令行参数参数说明--output-dir, -o生成 QML 的输出目录与--list-outputs二选一--dry-run, -n只打印将要生成的内容不写文件--custom-pages-dir自定义构建的页面目录可提供SettingsPages.json覆盖层与同名页面定义遮蔽--custom-settings-dir自定义构建的设置目录提供额外的*.SettingsGroup.json事实元数据--list-outputs只打印将要生成的 QML 文件名每行一个供 CMake 在覆盖层生效时动态计算输出清单手动运行生成器做一次试生成的命令为需在仓库根目录执行python3 -m tools.generators.settings_qml.generate_pages --output-dir src/AppSettings注意实际构建由 CMake 驱动GENERATE_AT_CONFIGURECONFIGURE_DEPENDS修改 JSON 或生成器源码后重新构建即自动再生成日常开发通常无需手工执行。SettingsPages.json侧边栏页面列表src/AppSettings/pages/SettingsPages.json 定义设置侧边栏的页面顺序。顶层结构为{ version: 1, fileType: SettingsPages, pages: [ { divider: true }, { name: General, qml: GeneralSettings.qml, icon: qrc:/res/QGCLogoWhite.svg, pageDefinition: General.SettingsUI.json } ] }页面条目Page Entry的键定义键类型说明namestring侧边栏显示名称iconstring侧边栏图标的qrc:路径qmlstring输出文件名如GeneralSettings.qmlpageDefinitionstring用于生成的*.SettingsUI.json文件名urlstring手写 QML 页面的qrc:URL绕过生成visiblestringQML 表达式为假时该条目隐藏dividerbool插入可视分隔线而非页面条目约束每个页面条目必须且只能有pageDefinition生成或url手写二者之一。仓库真实条目正好覆盖了全部形态生成页General、Fly View、Plan View、ADSB Server、Comm Links、App Logging、Maps、NTRIP/RTK、PX4 Log Transfer、Remote ID、Telemetry、Video、3D View手写页无pageDefinition只有qmlApp Log ViewerAppLogging.qml、HelpHelpSettings.qml、Mock Link、Debug、Palette Test分隔线两处{ divider: true }条件可见页NTRIP/RTK要求ntripSettings存在PX4 Log Transfer要求showPX4LogTransferOptions且 PX4 固件受支持Video、3D View分别绑定videoSettings.userVisible、viewer3DSettings.userVisibleMock Link、Debug、Palette Test仅在ScreenTools.isDebug时出现。SettingsUI.json单页布局定义与完整 Schema*.SettingsUI.json描述单个设置页的布局。顶层对象键类型必填说明fileTypeSettingsUI是必须为SettingsUIversion1是Schema 版本bindingsobject否命名的 QML 属性绑定如访问器别名groupsarray of group是页面展示的设置分组bindings是给长访问器起别名的标准方式别名可在页面任意位置作为 QML 属性使用bindings: { _appSettings: QGroundControl.settingsManager.appSettings }src/AppSettings/pages/General.SettingsUI.json 正是这样做的顶层声明_appSettings绑定随后在audioVolume滑块的enableCheckbox.onClicked中直接使用_appSettings.audioMuted.rawValue。group一个可折叠分组可带标题键类型必填说明headingstring否分组标题可翻译headingDescriptionstring否标题下动态描述的 QML 表达式showWhenstring否QML 表达式为假时隐藏整组enableWhenstring否QML 表达式为假时禁用整组sectionNamestring否树形导航显示名缺省回退到headingkeywordsarray of string否额外搜索词componentstring否嵌入的手写 QML 组件名替代控件生成missingarray of string否尚未生成的复杂 UI 的说明仅文档用途controlsarray of control见说明组内控件设置了component时可不提供General.SettingsUI.json中的Units分组即用showWhen: QGroundControl.settingsManager.unitsSettings.userVisible做条件显示且每个单位设置都显式声明control: combobox。control键类型必填说明settingstring是指向 Fact 的点分路径如appSettings.qLocaleLanguagelabelstring否覆盖标签留空则用fact.labelcontrolstring否显式控件类型见下文省略时自动检测showWhenstring否额外可见性 QML 表达式与fact.userVisible做逻辑与enableWhenstring否绑定到enabled的 QML 表达式placeholderstring否文本框占位符propertiesobject否给browse/scaler控件注入的额外 QML 属性绑定enableCheckboxobject否滑块的启用复选框见下文buttonobject否相邻按钮见下文setting的值必须是settingsGroupAccessor.factName形式访问器与 CSettingsManager属性名一致如appSettings、flyViewSettings、autoConnectSettings。在General.SettingsUI.json中可以看到多种典型写法appSettings.qLocaleLanguagecombobox、appSettings.indoorPalette省略 control自动检测、appSettings.uiScalePercentscaler、appSettings.savePathbrowse showWhen: !ScreenTools.isMobile、unitsSettings.horizontalDistanceUnitscombobox跨设置组访问。控件类型与自动选择逻辑当*.SettingsUI.json省略control时生成器会读取*.SettingsGroup.json元数据中的 Fact 类型来自动选择控件Fact 类型默认控件boolcheckboxFactCheckBoxSlider带enumStringscomboboxLabelledFactComboBox数值textfieldLabelledFactTextField显式control值可覆盖自动选择值实际控件comboboxLabelledFactComboBoxtextfieldLabelledFactTextFieldcheckboxFactCheckBoxSliderslider滑块可带启用复选框与相邻按钮browse文件/路径浏览器仅桌面端需配showWhen: !ScreenTools.isMobilescaler百分比缩放控件用于uiScalePercentslider 的扩展键enableCheckbox{ checked: expr, onClicked: body }button{ text: label, onClicked: body, enabled: expr }。仓库中audioVolume是一个完整范例{ setting: appSettings.audioVolume, control: slider, enableCheckbox: { checked: !_appSettings.audioMuted.rawValue, onClicked: { if (enableCheckBoxChecked _appSettings.audioVolume.rawValue 0) _appSettings.audioVolume.rawValue 75; _appSettings.audioMuted.rawValue !enableCheckBoxChecked } }, button: { text: Test, onClicked: QGroundControl.testAudioOutput(), enabled: !_appSettings.audioMuted.rawValue _appSettings.audioVolume.rawValue 0 } }即勾选启用复选框时若音量为 0 则自动拉到 75并同步audioMuted状态Test 按钮只有未静音且音量大于 0 时才可用点击触发QGroundControl.testAudioOutput()。browse / scaler 的 propertiesproperties把 QML 属性名映射为值注入控件布尔与数字按 QML 字面量输出字符串原样作为 QML 表达式输出。例如让browse选择文件而非文件夹{ setting: viewer3DSettings.osmFilePath, control: browse, showWhen: !ScreenTools.isMobile, properties: { selectFolder: false, nameFilters: [ qsTr(\OpenStreetMap files (*.osm)\) ] } }objectName 约定UI 测试钩子生成页面会输出稳定的objectName供 test/QmlUITests/ 通过QmlUITestBase::findVisibleItem稳定定位控件避免脆弱的文本/遍历匹配条目objectName页面根settingsPage_PageName非[A-Za-z0-9_]字符剔除如settingsPage_RemoteID分组SettingsGroupLayout仅带标题的分组settingsGroup_Heading同样剔除非法字符如settingsGroup_EUVehicleInfo文本框LabelledFactTextFieldsettingsTextField_factName复选框FactCheckBoxSlidersettingsCheckBox_factName页面名与标题在嵌入 objectName 前会净化到[A-Za-z0-9_]若标题净化后为空串或同一页面两个标题净化后产生相同 objectName生成会直接报错需重命名标题解决。手写页面 src/AppSettings/pages/../QmlControls/SettingsPage.qml 的内容 Flickable 命名为settingsPageFlickable配合QmlUITestBase::scrollIntoView使用参考示例见test/QmlUITests/RemoteIDSettingsUITest.cc。侧边栏、分节与搜索生成的SettingsPagesModel.qml由SettingsPages.json与每个页面定义构建包含sections可展开侧边栏行的分节名称searchTerms页面/分节/Fact 关键词 token供 src/QmlControls/AppSettings.qml 中的搜索框使用。搜索词来源页面名称分节标题/名称Fact 元数据中的keywords使用component分组未提供显式控件时的组级keywords这与 src/Settings/App.SettingsGroup.json 的字段一一对应每个 Fact 都带keywords如firmware,ardupilot,px4页面 JSON 的分组也带keywords如General页的language,locale,color scheme,dark mode,...。实战一向现有生成页面新增一个设置项三步走构建后自动生效添加 Fact 元数据在合适的src/Settings/Group.SettingsGroup.json中新增条目。可参考 src/Settings/App.SettingsGroup.json 的既有字段name、type、default、label、shortDesc/longDesc、keywords枚举型还需enumStrings/enumValues数值型可加min/max/userMin/userMax/units/decimalPlaces。暴露 Fact在对应的*Settings.h中加DEFINE_SETTINGFACT(factName)按该文件既有模式需要时在*Settings.cc中确保DECLARE_SETTINGSFACT存在。添加控件条目在src/AppSettings/pages/Page.SettingsUI.json中加{ setting: accessor.factName }可叠加control、showWhen、enableWhen等键。完整 JSON Schema 参考 tools/generators/settings_qml/README.md。最后重新构建 QGCCMake 会自动重新生成该页 QML因为_page_definitions与_settings_metadata均带CONFIGURE_DEPENDS。实战二新增一个完整的生成设置页在src/AppSettings/pages创建新页面定义 JSON如MyFeature.SettingsUI.json。在 src/AppSettings/pages/SettingsPages.json 新增条目name、icon、qml输出文件名、pageDefinition新 JSON 文件名可选visible表达式。更新 src/AppSettings/CMakeLists.txt 的生成输出清单把新 QML 文件名加进_generated_qml_names该清单是显式的漏加会导致构建集成不完整。构建 QGC新页面即被生成并纳入QGroundControl.AppSettings模块。实战三自定义构建QGC_CUSTOM_DIR覆盖设置体系自定义构建QGC_CUSTOM_DIR可以不覆盖仓库内生成的 QML而是通过覆盖层增加、替换、重排或删除生成页页面列表覆盖层创建custom/src/AppSettings/pages/SettingsPages.json。其条目在配置期与内置页面列表合并name与内置页相同的条目原位替换该页新条目可用insertAfter/insertBefore引用内置页name控制位置否则追加到末尾{ remove: name }删除内置页。页面定义把*.SettingsUI.json放进同一自定义 pages 目录与内置定义同名的文件遮蔽内置定义。自定义设置组当需要引用内置 QGC 不存在的 Fact 时在custom/src/Settings/Name.SettingsGroup.json添加 Fact 元数据并把它以:/json资源前缀编译进应用为其创建SettingsGroup子类重写QGCCorePlugin::registerCustomSettings调用SettingsManager::registerCustomSettingsGroup(accessor, new MySettings())管理器接管所有权。访问器必须是 JSON 文件名的 camelCase 词干加Settings例如Custom.SettingsGroup.json→customSettings这样生成页才能解析QGroundControl.settingsManager.accessor.fact。自定义词干若与内置SettingsManager访问器冲突会被拒绝。CMake 在自定义目录存在时自动接线src/AppSettings/CMakeLists.txt 会追加--custom-pages-dir、--custom-settings-dir生成输出清单由生成器的--list-outputs模式动态计算无需手工维护Python 在 Windows 上输出 CRLFCMake 已做\r归一化处理。仓库中的 custom-example 自定义构建提供了上述全部机制的完整可运行示例覆盖层新增自定义设置页、其页面定义、自定义设置组Fact 元数据 SettingsGroup子类与插件注册覆写。重要注意事项汇总SettingsPages.json中无pageDefinition的页面被视为手写 QML/URL 内容不参与生成。CMake 的_generated_qml_names列表是显式的新增输出文件名忘记登记会导致构建集成不完整。*.SettingsUI.json中的setting路径必须匹配合法的QGroundControl.settingsManager.group.fact访问器。Fact 标签应写入元数据缺失标签会在运行时由SettingsGroup记录日志。结语从 JSON 到界面的一次性映射整体来看QGC 设置视图的设计哲学是声明式 生成式*.SettingsGroup.json提供事实类型、枚举、范围、关键词*.SettingsUI.json提供布局分组、控件、可见性SettingsPages.json提供导航结构三者经 tools/generators/settings_qml 的 Python 生成器模板位于tools/generators/settings_qml/templates/*.j2在构建期翻译成稳定的 QML再由 src/QmlControls/AppSettings.qml 运行时加载渲染。无论是日常添加一个开关、构建一个全新设置页还是为定制版本做完整的分支覆盖都可以在不手写 QML 的前提下仅靠编辑 JSON 与重新构建完成——这正是这套机制对二次开发最大的价值所在。赞分享无人机智能硬件【免费下载链接】qgroundcontrolCross-platform ground control station for drones (Android, iOS, Mac OS, Linux, Windows)项目地址https://gitcode.com/gh_mirrors/qg/qgroundcontrol点击查看免费下载相关推荐Bilibili视频转文字终极指南如何免费快速提取视频内容Bilibili视频转文字终极指南如何免费快速提取视频内容 Bilibili视频转文字 工具 bili2text 是一个开源免费的视频内容提取解决方案它能够无人机智能硬件MkDocs Material 更换 Logo 与图标从内置图标库到自定义 SVG 的完整配置指南MkDocs Material 更换 Logo 与图标从内置图标库到自定义 SVG 的完整配置指南 本篇指南以 Material for MkDocs 的「更无人机智能硬件如何免费突破网盘下载限速3个简单步骤实现高速文件传输如何免费突破网盘下载限速3个简单步骤实现高速文件传输 还在为网盘下载速度慢而烦恼吗每天都有无数用户面对这样的困境重要文件下载缓慢大文件传输耗时过长免费上一篇vnpy 价差交易模块 SpreadTrading 实战指南价差合约构建、算法执行与策略开发下一篇New API 日文版指南精读部署、环境变量与多机集群配置实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考