4. 第一个插件

好,咱们正式开始动手写代码了。

这一章的目标很简单——创建一个能加载到 QGroundControl 里的插件项目,让它弹个 "Hello World" 出来。别小看这一步,我见过不少新手卡在项目结构上,折腾半天连编译都过不去。

4.1 创建插件项目

QGC 的插件机制,说白了就是一套约定好的目录结构和接口。你按它的规矩来,它就能识别你的代码。

我个人习惯在 QGC 源码的 src/ 下建一个 plugins/ 目录,专门放自定义插件。当然你也可以放别处,但放这里方便一起编译。

项目结构清单

  • HelloWorldPlugin/ — 插件根目录
  • HelloWorldPlugin.qml — 插件入口文件
  • HelloWorldPlugin.json — 插件元数据
  • CMakeLists.txt — 编译配置

先建文件夹:

mkdir -p src/plugins/HelloWorldPlugin

然后创建 HelloWorldPlugin.json,这是插件的身份证:

{
  "name": "HelloWorldPlugin",
  "version": "1.0.0",
  "description": "我的第一个 QGC 插件",
  "author": "你的名字",
  "main": "HelloWorldPlugin.qml",
  "type": "ui"
}

这里有个坑——type 字段必须写 "ui",否则 QGC 不会把它当成界面插件加载。我曾经手滑写成 "UI",结果调试了一下午。

4.2 编写插件入口

入口文件 HelloWorldPlugin.qml 才是核心。QGC 的插件系统基于 QML,所以你得用 QML 语法来写。

import QtQuick 2.4
import QtQuick.Controls 1.3

Item {
  id: root
  width: 200
  height: 100

  Rectangle {
    anchors.fill: parent
    color: "#f0f8ff"
    border.color: "#3498db"
    border.width: 2
    radius: 8

    Text {
      anchors.centerIn: parent
      text: "Hello World!"
      font.pixelSize: 18
      color: "#2c3e50"
    }
  }
}

这段代码干了三件事:

  • 定义了一个 Item 作为根组件
  • 里面放了个带边框的矩形
  • 矩形中间显示 "Hello World!" 文字

嗯,这里要注意——anchors.centerIn: parent 是 QML 里最常用的居中写法,别写成 anchors.centerIn: root,虽然效果一样,但语义上 parent 更清晰。

4.3 注册插件

光有文件还不够,你得告诉 QGC 编译系统:嘿,这里有个新插件要加进来。

打开 src/plugins/CMakeLists.txt,在合适位置加上:

add_subdirectory(HelloWorldPlugin)

然后在 HelloWorldPlugin/CMakeLists.txt 里写:

set(PLUGIN_NAME HelloWorldPlugin)

qt5_add_resources(PLUGIN_RESOURCES
  HelloWorldPlugin.qrc
)

add_library(${PLUGIN_NAME} SHARED
  ${PLUGIN_RESOURCES}
)

target_link_libraries(${PLUGIN_NAME}
  Qt5::Quick
  Qt5::Qml
)

等等,还差一个 .qrc 文件。QGC 用 Qt 资源系统来管理 QML 文件,所以你得创建 HelloWorldPlugin.qrc:

<RCC>
  <qresource prefix="/plugins/HelloWorldPlugin">
    <file>HelloWorldPlugin.qml</file>
    <file>HelloWorldPlugin.json</file>
  </qresource>
</RCC>

路径前缀必须一致

prefix 里的路径要和 json 里的 main 字段对应。否则 QGC 找不到入口文件,插件直接不加载。

4.4 编译与加载验证

编译步骤和普通 QGC 一样:

cd ~/QGC
mkdir build && cd build
cmake ..
make -j4

编译成功后启动 QGC,打开 设置 → 插件管理,你应该能看到 HelloWorldPlugin 出现在列表里。

点击启用,然后回到主界面——如果一切正常,右上角会多出一个 "Hello World!" 的小窗口。

验证小技巧

如果插件没出现,先检查 ~/.config/QGroundControl.org/QGroundControl.ini 里有没有 plugin/HelloWorldPlugin/enabled=true。没有的话手动加一行,重启 QGC。

为什么会这样?因为 QGC 的插件启用状态是持久化在配置文件里的。第一次加载时默认禁用,你得手动开一下。

4.5 知识结构图

下面这张图把整个流程串起来了,你对照着看会更清楚:

HelloWorld 插件开发流程 创建项目目录 编写 QML 入口 注册到 CMake 编译 QGC 加载 & 验证 调试 & 修复 虚线箭头表示调试回退:验证失败时返回修改入口或注册配置

4.6 常见问题速查表

问题现象 可能原因 解决办法
插件列表为空 CMake 未添加子目录 检查 src/plugins/CMakeLists.txt
插件显示但无法启用 .qrc 路径前缀错误 核对 prefix 与 json 的 main
启用后界面无变化 QML 语法错误 查看 QGC 日志(--debug 启动)
编译报错找不到头文件 缺少 target_link_libraries 加上 Qt5::Quick 和 Qt5::Qml

说实话,第一次跑通这个流程,你基本就掌握了 QGC 插件开发的骨架。后面所有插件都是在这个框架上长出来的。

我记得自己第一次写这个插件时,卡在 .qrc 文件上整整两小时——明明文件都在,就是加载不出来。后来发现是 prefix 少写了一个斜杠。这种小错误,你遇到了也别慌,按上面的表排查就行。