znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第05章 - 动作详解(一):鼠标操作

从本章开始,我们进入 robotgo-flow 的核心——动作(Action)的详细讲解。动作是工作流的最小执行单元,框架共支持 19 种。本章聚焦四种鼠标类动作:click(单击)、double_click(双击)、right_click(右键)、drag(拖拽)。

5.1 鼠标动作的两种定位方式

所有点击类动作(click/double_click/right_click)都支持两种定位目标的方式:

  1. 模板匹配:给一个模板图片路径,框架在屏幕上找到该图片,在其中心执行操作;
  2. 绝对坐标:直接给 x/y 屏幕坐标,框架在该坐标执行操作。

这源于源码中的 parseTargetedAction 泛型解析逻辑:它既接受字符串(模板路径),也接受包含 x/y 键的映射。对应的执行逻辑在 click.goresolveTarget 方法中:若指定了坐标就直接使用,否则调用 eng.FindElement(template) 通过图像匹配定位。

如何取舍? 模板匹配更健壮,能适应窗口移动、布局微调,是推荐的主流方式;绝对坐标更快、更简单,适用于位置固定、分辨率固定的场景,但一旦窗口移动或分辨率变化就会失效。

5.2 click:单击

单击是最常用的动作。两种写法:

# 方式一:模板匹配(推荐)
- click: "templates/button.png"

# 方式二:绝对坐标
- click: {x: 500, y: 300}
  • 模板匹配版:框架在屏幕上查找 button.png,找到后在其中心位置单击。若在 element_timeout 内找不到,会按当前的错误策略处理(默认 abort 终止)。
  • 坐标版:直接在屏幕坐标 (500, 300) 处单击。

在引擎内部,单击最终会调用 robotgo.Click();若启用了人类行为模拟,鼠标会先以贝塞尔曲线轨迹移动到目标位置,再执行点击,并带有随机延时。

5.3 double_click:双击

双击用于打开文件、选中词组等场景:

# 模板匹配
- double_click: "templates/item.png"

# 绝对坐标
- double_click: {x: 500, y: 300}

引擎内部会执行两次点击,两次之间有一个短暂间隔(普通模式约 100ms,人类模式为 60~200ms 的随机间隔),以模拟真实的双击节奏——间隔过短或过长都可能不被目标程序识别为「双击」。

5.4 right_click:右键单击

右键常用于呼出上下文菜单:

# 模板匹配
- right_click: "templates/menu_area.png"

# 绝对坐标
- right_click: {x: 500, y: 300}

内部调用 robotgo.Click("right"),即以右键执行点击。呼出菜单后,通常再配合 wait(等待菜单项出现)与 click(点击菜单项)来完成一次完整的右键菜单操作。

5.5 drag:拖拽

拖拽动作与前三者不同,它需要两个目标——起点和终点,且都以模板形式给出:

- drag: {from: "templates/source.png", to: "templates/target.png"}

对应源码中的 DragSpec 结构,包含 fromto 两个模板路径字段。执行逻辑在 drag.go 中:

  1. FindElement(fromTemplate) 定位起点中心;
  2. FindElement(toTemplate) 定位终点中心;
  3. 调用 eng.Drag(from.X, from.Y, to.X, to.Y) 执行拖拽。

引擎内部的拖拽实现是:在起点按下鼠标左键(MouseDown),移动到终点,再释放(MouseUp,通过 defer 保证一定释放)。这适用于拖动文件、滑块、调整元素位置等场景。

注意drag 的起点和终点都必须是模板,不支持直接给坐标。如果需要拖到固定坐标,需要先在该位置准备一个可识别的模板图片。

5.6 鼠标动作的执行细节

理解鼠标动作背后的引擎行为,有助于你写出更可靠的工作流。

5.6.1 移动到目标(moveTo)

在执行任何点击前,引擎会先把鼠标移动到目标位置(moveTo):

  • 普通模式:调用 robotgo.MoveSmooth(x, y) 平滑移动,然后短暂延时约 100ms;
  • 人类模式:调用人类行为模块的 moveMouseTo,走贝塞尔曲线轨迹(详见第 11 章),并带有随机的「点击前延时」。

5.6.2 操作后延时(delay)

每个动作执行完后,引擎会有一个延时再进入下一个动作:

  • 普通模式:固定约 500ms(defaultDelay);
  • 人类模式:200~800ms 的随机延时。

这个延时的意义在于:真实的 UI 往往需要一点响应时间(比如点击后弹出菜单、页面重绘),过快的连续操作可能导致「点空」或状态不同步。

5.7 综合示例:右键菜单操作

下面用一个完整的步骤演示鼠标动作的组合使用——右键呼出菜单,然后点击其中的「复制」项:

steps:
  - name: "右键复制"
    actions:
      - right_click: "templates/target_item.png"   # 右键目标
      - wait: "templates/menu_copy.png"             # 等待菜单出现
      - click: "templates/menu_copy.png"            # 点击「复制」
      - sleep: 0.5                                   # 稍等片刻

再看一个拖拽排序的例子:

steps:
  - name: "拖动排序"
    actions:
      - drag: {from: "templates/row_item.png", to: "templates/drop_zone.png"}
      - wait: "templates/reorder_done.png"

5.8 常见问题

问题 可能原因 解决方法
点击位置偏移 窗口未最大化、标题栏高度变化 保证截图与运行时窗口状态一致;框架会自动最大化浏览器窗口
找不到模板,动作失败 分辨率/DPI 不一致、UI 内容变化 在目标机器上重新截取模板,关闭显示缩放
双击未被识别 间隔异常 通常无需干预,框架已按合理间隔实现;必要时改用两次单击测试
拖拽没有效果 目标程序对拖拽速度敏感 尝试启用人类模式让轨迹更自然,或检查起终点模板是否准确

5.9 小结

本章我们详解了四种鼠标动作:clickdouble_clickright_click 支持模板匹配与绝对坐标两种定位方式;drag 则需要起点和终点两个模板。我们还深入了引擎在执行鼠标动作时的移动与延时细节,理解了普通模式与人类模式的区别,并通过右键菜单、拖拽排序两个例子演示了动作组合。下一章,我们继续讲解键盘类动作。