81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
|
|
"""L2 Locator 抽象层基类:GeomSpec + Selector + ElementHandle。
|
|||
|
|
|
|||
|
|
GeomSpec:几何定位规格(relative_to / ratio / offset)
|
|||
|
|
Selector:UI 元素选择器(kind / by_image / by_geom / threshold / require_image)
|
|||
|
|
ElementHandle:定位结果句柄(绝对坐标 + 置信度 + 策略)
|
|||
|
|
|
|||
|
|
L3 Actions 通过 Selector 描述要找的元素,LocatorRegistry 解析为
|
|||
|
|
ElementHandle(图像命中或几何兜底),Actions 据此调 Backend 执行点击。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from dataclasses import dataclass
|
|||
|
|
from typing import Optional
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class GeomSpec:
|
|||
|
|
"""几何定位规格。
|
|||
|
|
|
|||
|
|
relative_to 取值:window / window_top_left / window_bottom_right(语义占位,
|
|||
|
|
实际计算统一用 ratio + offset,offset 已含正负号区分方向)。
|
|||
|
|
|
|||
|
|
所有字段带默认值,避免构造时必填字段顺序问题。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
relative_to: str = "window"
|
|||
|
|
x_ratio: float = 0.0
|
|||
|
|
y_ratio: float = 0.0
|
|||
|
|
x_offset: int = 0
|
|||
|
|
y_offset: int = 0
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class Selector:
|
|||
|
|
"""UI 元素选择器。
|
|||
|
|
|
|||
|
|
kind:元素类别键(如 search_box / send_button / input_box)
|
|||
|
|
by_image:图像模板名(P2 启用),非空时优先图像匹配
|
|||
|
|
by_geom:几何规格,非空时图像失败或 P1 阶段走几何兜底
|
|||
|
|
threshold:图像匹配置信度阈值(默认 0.80)
|
|||
|
|
require_image:高风险操作为 True 时,图像失败即拒绝执行
|
|||
|
|
description:人类可读描述
|
|||
|
|
|
|||
|
|
所有字段带默认值。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
kind: str = ""
|
|||
|
|
by_image: Optional[str] = None
|
|||
|
|
by_geom: Optional[GeomSpec] = None
|
|||
|
|
threshold: float = 0.80
|
|||
|
|
require_image: bool = False
|
|||
|
|
description: str = ""
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class ElementHandle:
|
|||
|
|
"""定位结果句柄。
|
|||
|
|
|
|||
|
|
selector:来源 Selector(回溯用)
|
|||
|
|
x / y:元素中心绝对坐标(点击点)
|
|||
|
|
w / h:元素宽高(图像匹配时返回,几何兜底为 0)
|
|||
|
|
confidence:匹配置信度(图像命中时为模型分数,几何兜底为 1.0)
|
|||
|
|
strategy:定位策略 image / geom
|
|||
|
|
|
|||
|
|
所有字段带默认值。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
selector: Optional[Selector] = None
|
|||
|
|
x: int = 0
|
|||
|
|
y: int = 0
|
|||
|
|
w: int = 0
|
|||
|
|
h: int = 0
|
|||
|
|
confidence: float = 1.0
|
|||
|
|
strategy: str = "geom"
|
|||
|
|
|
|||
|
|
@property
|
|||
|
|
def center(self) -> tuple[int, int]:
|
|||
|
|
"""返回元素中心点(x, y)。"""
|
|||
|
|
return (self.x, self.y)
|