Pelco KBD300A 模拟器:07+1.宏脚本编辑器与模板库管理实现细节

第 7+1 篇 📝 宏脚本编辑器与模板库管理实现细节

引言

在上篇《7. 宏脚本编辑器设计与解释器实现》中,我们构建了宏系统的核心执行引擎,从词法分析、语法解析到 AST 解释执行,实现了自动巡航、批量预置位、报警联动等高级功能。本篇将视角从"引擎内部"转向"用户界面",深入讲解宏编辑器(macro_editor.py)与模板库(template_library.py)的设计与实现。

这两部分共同构成了宏系统的"前端入口",让用户能够:

  • 可视化编写脚本
  • 一键加载模板
  • 参数化生成脚本
  • 保存/管理宏文件
  • 直接运行并查看执行进度

相比早期单文件版(KBD300A_main.py)完全没有宏功能,最终版通过 QsciScintilla 编辑器 + JSON 模板库 + 完整 AST 引擎,实现了一个可扩展、可维护、可复用的企业级脚本系统。


🛠️ 宏编辑器设计(MacroEditorPanel)

宏编辑器是用户与宏系统交互的核心界面。设计目标非常明确:

  • 专业编辑体验(语法高亮、行号、缩进)
  • 文件管理(新建、保存、删除)
  • 运行/停止控制
  • 进度反馈

最终选择 QsciScintilla 作为编辑器组件,它比 QTextEdit 更适合做代码编辑器。


🔧 UI 结构

编辑器采用典型的三段式布局:

  1. 顶部工具栏:宏列表 + 新建/保存/删除
  2. 中间编辑区:QsciScintilla
  3. 底部控制区:运行/停止 + 进度条

代码片段(来自最终实现):

python 复制代码
self.editor = QsciScintilla()
lexer = QsciLexerLua(self.editor)
self.editor.setLexer(lexer)
self.editor.setUtf8(True)
self.editor.setIndentationsUseTabs(False)
self.editor.setIndentationWidth(4)
self.editor.setMarginLineNumbers(1, True)
self.editor.setMarginWidth(1, "0000")

QsciLexerLua 虽然不是专为宏语言设计,但其结构与我们 DSL 的语法足够接近,能提供良好的高亮体验。


▶️ 运行与停止

运行宏的逻辑非常简洁:

python 复制代码
def _run(self):
    script = self.editor.text()
    self.run_macro.emit(script)
    self.progress.setValue(0)

这里不直接执行脚本,而是通过信号交给 AppWindow → MacroEngine,保持 UI 与逻辑完全解耦。

停止宏:

python 复制代码
def _stop(self):
    if hasattr(self.parent(), "_stop"):
        self.parent()._stop()

最终由 MacroEngine.stop() 触发安全停止(包括 PTZ 强制停止)。


📁 文件管理

宏文件存储在:

复制代码
resources/macros/*.macro

加载:

python 复制代码
for f in os.listdir(MACRO_DIR):
    if f.endswith(".macro"):
        self.macro_list.addItem(f[:-6])

保存:

python 复制代码
with open(path, "w", encoding="utf-8") as f:
    f.write(self.editor.text())

删除:

python 复制代码
os.remove(path)
self.load_macros()

整个编辑器保持轻量、直观、可扩展。


📚 模板库管理(TemplateLibraryPanel)

模板库是宏系统的"生产力工具"。它允许用户:

  • 一键加载常用脚本
  • 使用参数化模板生成脚本
  • 快速构建巡航、批量预置位、报警联动等场景

模板存储在 JSON 文件中:

复制代码
resources/templates.json

结构示例:

json 复制代码
{
  "templates": [
    {
      "name": "停车场巡航",
      "description": "循环巡航 1-5 号预置位",
      "script": "loop(5){ send_preset(1, {{preset}}); delay(1000); }",
      "params": ["preset"]
    }
  ]
}

🔄 模板加载
python 复制代码
def load_templates(self):
    with open(TEMPLATE_FILE, "r", encoding="utf-8") as f:
        data = json.load(f)
        self.templates = data.get("templates", [])

UI 列表自动刷新:

python 复制代码
for tpl in self.templates:
    self.template_list.addItem(tpl["name"])

🧩 参数化模板渲染

模板支持 {``{param}} 占位符,渲染逻辑:

python 复制代码
def _render_template(self, tpl):
    script = tpl["script"]
    for param in tpl["params"]:
        value = input(f"Enter {param}: ")  # 实际实现为 QDialog
        script = script.replace(f"{{{{{param}}}}}", value)
    return script

最终脚本通过信号发送给编辑器:

python 复制代码
self.load_template.emit(script)

🔗 编辑器与模板库的集成

RightPanel 将两者组合到同一个 TabWidget 中:

python 复制代码
self.tabs.addTab(self.macro_editor, "宏编辑")
self.tabs.addTab(self.template_panel, "模板库")

AppWindow 负责信号路由:

python 复制代码
self.right.run_macro.connect(self._run_macro)

键盘切换到宏模式时自动跳转:

python 复制代码
if mode == "MACRO":
    self.right.tabs.setCurrentWidget(self.right.macro_editor)

模板库 → 编辑器 → 引擎 的链路完全打通。


🧠 宏引擎与 AST 的协作(关键补充)

你的最终版 MacroEngine 使用 访问者模式(Visitor Pattern) 执行 AST:

python 复制代码
def visit(self, node):
    method_name = f'visit_{type(node).__name__}'
    visitor = getattr(self, method_name, self.generic_visit)
    return visitor(node)

支持:

  • Compound
  • Loop
  • For
  • Command
  • Var / Num / String

执行命令:

python 复制代码
if name == 'send_preset':
    pelco.call_preset(self.serial_mgr, current_cam, preset)

delay 使用可中断版本:

python 复制代码
self._delay_interruptible(ms)

整个执行器是同步的、可测试的、可扩展的。


🛡️ 调试与优化

  • AST 可视化:在 visit_* 中加入 debug 输出
  • 模板校验:使用 JSON schema
  • 自动补全:QsciScintilla 支持 API 文件,可加入 send_preset/loop/delay 等关键字
  • 错误提示:解析错误通过 error.emit 弹窗
  • Win7 兼容性:QsciScintilla 性能优于 QTextEdit,长脚本不卡顿

🏁 结语

本篇文章从 UI 到模板库,从脚本编辑到 AST 执行,完整展示了宏系统的"前端生态"。宏编辑器让脚本编写更直观,模板库让脚本复用更高效,而 MacroEngine 则提供了强大的执行能力。

三者结合,使得 KBD300A 工具从"控制台工具"升级为"自动化平台",为安防维护、巡航调试、批量配置提供了真正的生产力。

下一篇《7.2 Python 专题:线程安全与信号槽机制》将深入探讨宏执行的并发模型与 UI 响应优化。

上一篇 总目录 下一篇

相关推荐
weixin_438077492 分钟前
CS336 Assignment 4 (data): Filtering Language Modeling Data 翻译和实现
人工智能·python·语言模型·自然语言处理
小郭团队3 分钟前
未来PLC会消失吗?会被嵌入式系统取代吗?
c语言·人工智能·python·嵌入式硬件·架构
yesyesido3 分钟前
智能文件格式转换器:文本/Excel与CSV无缝互转的在线工具
开发语言·python·excel
环黄金线HHJX.6 分钟前
拼音字母量子编程PQLAiQt架构”这一概念。结合上下文《QuantumTuan ⇆ QT:Qt》
开发语言·人工智能·qt·编辑器·量子计算
王夏奇6 分钟前
python在汽车电子行业中的应用1-基础知识概念
开发语言·python·汽车
子夜江寒7 分钟前
基于PyTorch的CBOW模型实现与词向量生成
pytorch·python
He_Donglin7 分钟前
Python图书爬虫
开发语言·爬虫·python
天远Date Lab11 分钟前
Python金融风控实战:集成天远多头借贷行业风险版API实现共债预警
大数据·python
Python极客之家12 分钟前
基于深度学习的刑事案件智能分类系统
人工智能·python·深度学习·机器学习·数据挖掘·毕业设计·情感分析
Arvin_Zhang201614 分钟前
使用python实现从PDF格式的control mapping获取gross die数量
python·pdf