客户端插件说明(electricclawplugin-hmi)
开发环境
| 环境 | 工具链 |
|---|---|
| Windows | Qt 5.15.2、MSVC 2015 64-bit |
| linux X86 | GNU Compiler Collection 9.4 |
| linux aarch64 | gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu |
项目结构
代码文件夹包含 include 和 lib 文件夹,用于提供插件环境支持和必要的工具,在 Qt Creator 中打开 .pro 工程即可看到如下项目结构。

各部分说明:
| 组成 | 说明 |
|---|---|
| 配置文件(.pro) | Qt 编译配置文件(可理解为 Qt 版的 CMake),核心配置见下文 |
| 界面文件(.ui) | Qt Designer 可视化布局文件,构建后生成 ui_*.h 用于 UI 组件绑定 |
| 代码文件(.cpp/.h) | 界面类、业务逻辑类、插件入口类的声明与实现 |
| 资源文件(.qrc/.ts) | 控件文字翻译相关文件 |
.pro 核心配置
电爪项目 .pro 中与插件开发相关的关键配置:
TEMPLATE = lib # 构建为共享库(.dll/.so)
DEFINES += ELECTRICCLAWPLUGIN_LIBRARY # 控制导出/导入符号
DEFINES += PLUGIN_NAME=\\\"OnrobotPlugin\\\" # 插件注册名,用于完成插件注册
LIBS += -L$$PWD/lib/windows -lxplugin # 链接插件 SDK(xplugin)
INCLUDEPATH += $$PWD/include # SDK 头文件搜索路径
QT += widgets、CONFIG += c++11、FORMS、TRANSLATIONS、RESOURCES 等通用 qmake 配置说明见 制作一个简单的 HMI 插件。
代码文件组成
| 文件/模块 | 职责 |
|---|---|
| OnrobotPlugin.h/.cpp | 插件入口类 ElectricClawPlugin:插件注册、工艺包界面创建、RL 指令注册 |
| OnrobotWidget.h/.cpp/.ui | 工艺包主界面类 ElectricClawWidget:界面生成、信号槽绑定、初始化/运行/停止控制 |
| StatusPoller.h/.cpp | 状态轮询类:在子线程中以 200ms 周期查询电爪状态并通知界面刷新 |
| JsonWorker.h/.cpp | JSON 指令工作类:在线程池中异步发送插件指令,避免阻塞界面 |
| rl/RLStartWidget、RLStopWidget、RLStatusWidget | RL 指令界面类:根据窗口内单元的数据生成具体 RL 脚本 |
| OnrobotPlugin_global.h | 导出符号宏定义(ELECTRICCLAWPLUGIN_EXPORT) |
代码核心逻辑
插件注册
在 OnrobotPlugin.cpp 中通过宏声明实现插件的注册(PLUGIN_NAME 即 .pro 中定义的 OnrobotPlugin),插件加载时自动初始化插件类,并依次执行插件初始化函数 init() 和 afterInit():
XPLUGIN_REGISTER(PLUGIN_NAME, ElectricClawPlugin)
插件入口与界面注册

init() 中创建工艺包主界面 ElectricClawWidget,并通过 CreateCenterWidget 注册为中心控件:
void xplugin::ElectricClawPlugin::init()
{
m_widget = new ElectricClawWidget;
xplugin::CreateCenterWidget(PLUGIN_NAME, m_widget);
}
工艺包界面(ElectricClawWidget)
ElectricClawWidget 构造函数中完成信号槽绑定并启动状态监听:
- 创建
QThread子线程,将StatusPoller移入其中,线程启动后开始 200ms 周期的状态轮询; - 轮询结果
statusUpdated信号以 队列连接(Qt::QueuedConnection)方式绑到界面刷新槽函数,更新状态、力度、内宽、外宽四个显示框; - 为各输入框设置
QIntValidator范围限制(设备 ID 0255、力度 0140、速度 20100、宽度 160685)。
界面按钮的点击逻辑:
| 按钮 | 逻辑 |
|---|---|
| 初始化 | 先钳制输入值,再向设备发送一次 stop 指令作为"握手"校验;成功后记录设备 ID、使能运行/停止按钮及各参数输入框,失败则禁用并清空状态显示 |
| 运行 | 钳制输入值后,按界面参数(模式、宽度、力度、速度)组包发送 start 指令 |
| 停止 | 钳制输入值后,组包发送 stop 指令 |
此外,界面通过重写 showEvent/hideEvent 在工艺包页面 显示时开启轮询定时器、隐藏时关闭,避免后台空转。
clampLineEdit() 负责将输入框数值钳制到合法区间:非数字输入重置为最小值,超出上下限则钳到边界值。
JSON 指令收发(JsonWorker)
界面的所有请求都经 sendRequest() 发出:构造一个 JsonWorker(继承 QObject + QRunnable)投入全局线程池异步执行,完成后通过 finished 信号以队列连接回调界面,避免阻塞 UI 线程:
void JsonWorker::run()
{
QJsonArray result = xplugin::xPluginInterface().commandCustomData(nullptr, m_json);
emit finished(result);
}
发送的 JSON 协议与控制器插件注册的插件指令一一对应(见 控制器插件说明):
| 操作 | 发送的 JSON | 响应 |
|---|---|---|
| 停止/初始化握手 | {"ElectricClawPlugin":{"stop":{"slave_id":1}}} | {"return":true} |
| 启动 | {"ElectricClawPlugin":{"start":{"slave_id":1,"mode":1,"width":400,"force":50,"speed":50}}} | {"return":true} |
| 状态轮询 | {"ElectricClawPlugin":{"get_status":{"slave_id":1}}} | {"status":...,"external_width":...,"internal_width":...,"force":...,"return":true} |
状态轮询(StatusPoller)
StatusPoller 在子线程中运行,startPolling() 创建 QTimer 并以 200ms 周期触发 pollStatus():
- 设备未初始化(
m_is_init == false)时直接返回,不发送请求; - 组包
get_status指令调用commandCustomData查询,解析返回数组中ElectricClawPlugin → get_status节点,通过statusUpdated信号抛给界面线程刷新显示。
RL 指令注册


在 afterInit() 中通过 RLManager 注册 RL 编辑器指令(OnrobotMove、OnrobotStop、OnrobotStatus)。每条指令需注册五项内容:
m_rlManager->createTypeKey("OnrobotMove"); // 指令类型标识
m_rlManager->createSkeleton("OnrobotMove", "OnrobotMove"); // 指令骨架
m_rlManager->createInsDescribe("OnrobotMove", tr("...")); // 指令描述
m_rlManager->createPattern("OnrobotMove", "^\\s*...$"); // 匹配正则
m_rlManager->createInsertWidget("OnrobotMove", [](){ // 插入时的编辑控件
return new xplugin::RLStartWidget("OnrobotMove");
});
最后通过 createTypeToGroup 将三条指令归入 OnrobotPlugin 分组,并以 createGroups 设置分组显示标题。
这里注册的只是辅助编程的简化 RL 编写逻辑,不具备 RL 执行逻辑;RL 执行逻辑在控制器插件中实现,见 控制器插件说明。
RL 指令界面类
RL 指令界面类继承 RLContentBase,需实现三个接口:
| 接口 | 作用 |
|---|---|
ToString() | 将界面控件参数转换为指令字符串(生成 RL 脚本时调用) |
FillWith(str) | 用指令字符串反向填充界面(本示例仅打印调试日志,未做解析) |
CheckInsert() | 判断是否允许作为插入值(本示例固定返回 true) |
RLStartWidget::ToString() 示例——读取各控件值并拼接为 指令名 参数1,参数2,... 形式:
三个界面类的输出形式:
| 界面类 | 对应指令 | ToString 输出示例 |
|---|---|---|
| RLStartWidget | OnrobotMove | OnrobotMove 1,1,400,50,50(ID、模式、宽度、力度、速度) |
| RLStopWidget | OnrobotStop | OnrobotStop 1(ID) |
| RLStatusWidget | OnrobotStatus | OnrobotStatus 1,s,e,i,f(ID + 4 个下拉框文本) |
编译打包
- 打开 Qt Creator,选择构建类型(推荐 Release 用于发布)。
- 编译流程:qmake 解析 .pro 生成 Makefile → jom/make 执行编译 → 生成动态库(.dll)。

- 构建完成后在构建目录下即可找到生成的动态库。

打包规范与通用流程见 插件包制作,可直接使用 PluginPackage 打包脚本。