# ok-script API 文档 [English](../en/api_reference.md) · [文档中心](../index.md) · [快速开始](../quick_start/README.md) · [进阶指南](../after_quick_start/README.md) · [Web 自定义页](../task_web_tabs.md) 本文档是任务开发时的 API 参考。第一次使用 ok-script 时,请先完成[快速开始](../quick_start/README.md);查找具体方法时,可以使用浏览器的页面搜索功能按方法名定位。 ## 目录 - [Box](#box) - [Box.\_\_init\_\_](#box__init__) - [Box.area](#boxarea) - [Box.in\_boundary](#boxin_boundary) - [Box.scale](#boxscale) - [Box.center](#boxcenter) - [Box.copy](#boxcopy) - [Box.crop\_frame](#boxcrop_frame) - [Box.center\_distance](#boxcenter_distance) - [Box.closest\_distance](#boxclosest_distance) - [Box.relative\_with\_variance](#boxrelative_with_variance) - [Box.find\_closest\_box](#boxfind_closest_box) - [BaseTask](#basetask) - [名称匹配规则 (match / names)](#名称匹配规则-match--names) - [帧刷新与等待](#帧刷新与等待) - [截图 (Screenshot)](#截图-screenshot) - [frame](#frame) - [next\_frame](#next_frame) - [screenshot](#screenshot) - [adb\_ui\_dump](#adb_ui_dump) - [输入 (Input)](#输入-input) - [click](#click) - [click\_box](#click_box) - [click\_box\_if\_name\_match](#click_box_if_name_match) - [click\_relative](#click_relative) - [wait\_click\_box](#wait_click_box) - [right\_click](#right_click) - [middle\_click](#middle_click) - [swipe](#swipe) - [swipe\_relative](#swipe_relative) - [input\_text](#input_text) - [send\_key](#send_key) - [send\_key\_down](#send_key_down) - [send\_key\_up](#send_key_up) - [scroll](#scroll) - [scroll\_relative](#scroll_relative) - [mouse\_down](#mouse_down) - [mouse\_up](#mouse_up) - [move](#move) - [move\_relative](#move_relative) - [back](#back) - [Config 相关](#config-相关) - [load\_config](#load_config) - [validate\_config](#validate_config) - [get\_global\_config](#get_global_config) - [get\_global\_config\_desc](#get_global_config_desc) - [任务配置 (Task Configuration)](#任务配置-task-configuration) - [屏幕画图 (Screen drawing)](#屏幕画图-screen-drawing) - [draw\_boxes](#draw_boxes) - [get\_overlay\_view](#get_overlay_view) - [clear\_box](#clear_box) - [OCR](#ocr) - [ocr](#ocr) - [wait\_ocr](#wait_ocr) - [wait\_click\_ocr](#wait_click_ocr) - [add\_text\_fix](#add_text_fix) - [找图 (Image finding)](#找图-image-finding) - [find\_feature](#find_feature) - [find\_one](#find_one) - [wait\_feature](#wait_feature) - [wait\_click\_feature](#wait_click_feature) - [get\_box\_by\_name](#get_box_by_name) - [get\_feature\_by\_name](#get_feature_by_name) - [feature\_exists](#feature_exists) - [find\_feature\_and\_set](#find_feature_and_set) - [find\_best\_match\_in\_box](#find_best_match_in_box) - [find\_first\_match\_in\_box](#find_first_match_in_box) - [找色 (Color finding)](#找色-color-finding) - [calculate\_color\_percentage](#calculate_color_percentage) - [显示信息 (Display information)](#显示信息-display-information) - [notification](#notification) - [info\_set](#info_set) - [info\_get](#info_get) - [info\_incr](#info_incr) - [info\_add](#info_add) - [info\_add\_to\_list](#info_add_to_list) - [info\_clear](#info_clear) - [日志 (Logging)](#日志-logging) - [log\_info](#log_info) - [log\_debug](#log_debug) - [log\_error](#log_error) - [其他 (Other)](#其他-other) - [is\_adb](#is_adb) - [is\_browser](#is_browser) - [adb\_shell](#adb_shell) - [ensure\_in_front](#ensure_in_front) - [box\_of_screen](#box_of_screen) - [box\_of_screen\_scaled](#box_of_screen_scaled) - [screen\_width](#screen_width) - [screen\_height](#screen_height) - [width\_of_screen](#width_of_screen) - [wait\_until](#wait_until) - [wait\_scene](#wait_scene) - [sleep](#sleep) - [sleep_check](#sleep_check) - [run\_task\_by\_class](#run_task_by_class) - [tr](#tr) - [should\_trigger](#should_trigger) - [go\_to\_tab](#go_to_tab) - [find\_boxes](#find_boxes) --- ## Box `Box` 类用于表示屏幕上的一个矩形区域,通常用于标识UI元素、图像特征等。 ### Box.\_\_init\_\_ ```python def __init__(self, x, y, width=0, height=0, confidence=1.0, name=None, to_x=-1, to_y=-1) ``` 初始化一个 `Box` 对象。 - **参数:** - `x` (int): 矩形左上角的 x 坐标。 - `y` (int): 矩形左上角的 y 坐标。 - `width` (int): 矩形的宽度。如果提供了 `to_x`,则会自动计算。 - `height` (int): 矩形的高度。如果提供了 `to_y`,则会自动计算。 - `confidence` (float): 置信度,默认为 1.0。 - `name` (any): 矩形的名称或标识符。 - `to_x` (int): 矩形右下角的 x 坐标,用于计算宽度。 - `to_y` (int): 矩形右下角的 y 坐标,用于计算高度。 ### Box.area ```python def area(self) -> int ``` 计算并返回矩形的面积。 - **返回:** - `int`: 矩形的面积 (width * height)。 ### Box.in\_boundary ```python def in_boundary(self, boxes) -> list[Box] ``` 返回一个列表,其中包含传入参数 `boxes` 中所有位于当前 `Box` 边界内的 `Box` 对象。 - **参数:** - `boxes` (list[Box]): 要检查的 `Box` 对象列表。 - **返回:** - `list[Box]`: 位于边界内的 `Box` 列表。 ### Box.scale ```python def scale(self, width_ratio: float, height_ratio: float = None) ``` 按给定的宽高比缩放矩形,保持中心点不变。 - **参数:** - `width_ratio` (float): 宽度的缩放比例。 - `height_ratio` (float): 高度的缩放比例,如果为 `None` 则使用 `width_ratio`。 - **返回:** - `Box`: 一个新的、经过缩放的 `Box` 对象。 ### Box.center ```python def center(self) ``` 计算并返回矩形的中心点坐标。 - **返回:** - `tuple`: 包含中心点 (x, y) 坐标的元组。 ### Box.copy ```python def copy(self, x_offset=0, y_offset=0, width_offset=0, height_offset=0, name=None) ``` 创建一个带有偏移量的新 `Box` 副本。 - **参数:** - `x_offset` (int): x 坐标的偏移量。 - `y_offset` (int): y 坐标的偏移量。 - `width_offset` (int): 宽度的偏移量。 - `height_offset` (int): 高度的偏移量。 - `name` (any): 新矩形的名称。 - **返回:** - `Box`: 一个新的 `Box` 对象。 ### Box.crop\_frame ```python def crop_frame(self, frame) ``` 从给定的图像帧中裁剪出矩形区域。 - **参数:** - `frame` (numpy.ndarray): 要裁剪的图像帧。 - **返回:** - `numpy.ndarray`: 裁剪后的图像区域。 ### Box.center\_distance ```python def center_distance(self, other) -> float ``` 计算当前矩形与另一个矩形中心点之间的距离。 - **参数:** - `other` (Box): 另一个 `Box` 对象。 - **返回:** - `float`: 两个矩形中心点之间的欧几里得距离。 ### Box.closest\_distance ```python def closest_distance(self, other) -> float ``` 计算两个矩形边界之间的最短距离。如果两个矩形相交,则距离为 0。 - **参数:** - `other` (Box): 另一个 `Box` 对象。 - **返回:** - `float`: 两个矩形之间的最短距离。 ### Box.relative\_with\_variance ```python def relative_with_variance(self, relative_x=0.5, relative_y=0.5) -> tuple[int, int] ``` 返回矩形内的一个坐标点。支持相对位置并带有微小的随机偏移,模拟真实的人工点击。 - **参数:** - `relative_x` (float): 相对 x 坐标 (0.0 - 1.0)。 - `relative_y` (float): 相对 y 坐标 (0.0 - 1.0)。 - **返回:** - `tuple[int, int]`: 计算出的 (x, y) 坐标。 ### Box.find\_closest\_box ```python def find_closest_box(self, direction, boxes, condition=None) ``` 在给定方向上查找并返回距离最近的 `Box` 对象。 - **参数:** - `direction` (str): 查找方向 ('up', 'down', 'left', 'right', 'all')。 - `boxes` (list[Box]): 要在其中搜索的 `Box` 对象列表。 - `condition` (callable, optional): 一个可选的过滤函数,用于筛选 `Box`。 - **返回:** - `Box` 或 `None`: 找到的最近的 `Box` 对象,如果未找到则返回 `None`。 --- ## BaseTask `BaseTask` 是所有任务类的基类,它提供了任务执行所需的基础功能,如截图、输入、日志记录等。它继承自 `OCR`、`FindFeature` 和 `ExecutorOperation`,因此包含了这些父类的所有方法。 ### 名称匹配规则 (match / names) 多个 API 会用 `match` 或 `names` 参数过滤 `Box.name`,例如 `ocr`、`wait_ocr`、`wait_click_ocr`、`find_boxes` 和 `click_box_if_name_match`。 - `str`: 精确匹配,只有 `box.name == match` 才算匹配。 - `re.Pattern`: 正则匹配,使用 `re.search(pattern, box.name)`,所以可以匹配文本中的任意一段。 - `list[str | re.Pattern]`: 可以把字符串和正则任意组合在一个列表里,命中其中任意一个就会保留该 `Box`。 - 匹配默认区分大小写;需要忽略大小写时,用 `re.compile(..., re.IGNORECASE)`。 - 这不是模糊匹配,也不会自动做 `contains`。如果要匹配包含某段文字,请用正则,例如 `re.compile("开始|Start")`。 示例: ```python import re self.ocr(match="确定") # 只匹配 name 正好是 "确定" 的 OCR 结果 self.ocr(match=re.compile(r"确定|OK")) # 匹配包含 "确定" 或 "OK" 的结果 self.ocr(match=["确定", re.compile(r"^OK$")]) # 字符串和正则可以混用 ``` 在需要检测多个字符串或多个正则时,优先使用 `match=[...]` 一次 OCR 后统一过滤,通常比多次调用 `ocr` 更高效。 ### 帧刷新与等待 `frame` 是当前缓存的屏幕帧。`next_frame()` 和 `sleep()` 都会重置场景并清空当前缓存帧;带有 `after_sleep` 参数的方法也会在动作后调用 `sleep`,因此同样会清空当前帧。 当循环检测界面,或点击、滑动、按键后界面可能发生变化时,通常需要等待一下再读取新界面,例如: ```python self.click_box(button, after_sleep=0) self.sleep(0.5) boxes = self.ocr(match="确认") ``` 更推荐的写法是优先使用 `wait_` 开头的方法,例如 `wait_ocr`、`wait_click_ocr`、`wait_feature` 和 `wait_click_feature`。这些方法会自动循环获取新的 frame,调用前通常不需要额外 `sleep`。编写或生成脚本代码时,能用 `wait_` 方法表达的等待逻辑,尽量使用 `wait_` 方法。 ### 截图 (Screenshot) { #截图-screenshot } ### frame ```python @property def frame(self) ``` 获取当前有效的屏幕帧。此属性会确保返回的是最新的、可用的图像帧。如果脚本暂停,它会等待直到脚本恢复。 - **返回:** - `numpy.ndarray`: 当前的屏幕图像帧。 ### next\_frame ```python def next_frame(self) ``` 强制获取并返回一个新的屏幕帧。这会先重置场景并清空当前缓存帧,然后触发一次截图操作,而不是直接使用旧缓存。 - **返回:** - `numpy.ndarray`: 新捕获的屏幕图像帧。 ### screenshot ```python def screenshot(self, name=None, frame=None, show_box=False, frame_box=None) ``` 将当前屏幕或指定帧的图像保存到 `screenshots` 目录中,主要用于调试。保存的截图会显示在软件的UI界面中。 - **参数:** - `name` (str): 截图的名称,必须提供。 - `frame` (numpy.ndarray, optional): 如果提供,则保存该帧,否则保存当前屏幕帧。 - `show_box` (bool): 是否在截图上显示一个默认的框。 - `frame_box` (Box, optional): 在截图上显示的特定 `Box` 区域。 ### adb\_ui\_dump ```python def adb_ui_dump(self) -> str ``` 通过 ADB 获取当前屏幕的 UI 层级结构 XML 字符串(仅限安卓/模拟器模式)。 - **返回:** - `str`: UI 结构的 XML 字符串。 ### 输入 (Input) { #输入-input } ### click ```python def click(self, x: int | Box | List[Box] = -1, y=-1, move_back=False, name=None, interval=-1, move=True, down_time=0.02, after_sleep=0, key='left', hcenter=False, vcenter=False) ``` 在指定坐标或 `Box` 位置执行鼠标点击。坐标可以是绝对坐标(整数),也可以是相对于屏幕宽高的相对坐标(0.0到1.0之间的小数)。如果只提供了 `x` 参数且其类型为 `Box`,则会点击该 `Box` 的中心点。如果 `x` 是一个 `Box` 列表,则会点击列表中第一个 `Box` 的中心点。 - **参数:** - `x` (int | float | Box | list[Box]): x 坐标、相对 x 坐标或一个 `Box` 对象(或列表)。 - `y` (int | float): y 坐标或相对 y 坐标。 - `move_back` (bool): 点击后是否将鼠标移回原位。 - `name` (str, optional): 点击操作的名称,用于日志记录。 - `interval` (float): 距离上次点击的最小时间间隔(秒)。 - `move` (bool): 是否在点击前移动鼠标。 - `down_time` (float): 鼠标按下的持续时间(秒)。 - `after_sleep` (float): 点击后等待的时间(秒);会调用 `sleep`,因此会清空当前缓存帧。 - `key` (str): 要点击的鼠标按键 ('left', 'right', 'middle')。 - `hcenter`, `vcenter` (bool): 如果点击相对坐标且设为 True,则以屏幕中心为原点。 - **返回:** - `bool`: 如果操作成功执行,返回 `True`。 ### click\_box ```python def click_box(self, box: Box | List[Box] = None, relative_x=0.5, relative_y=0.5, raise_if_not_found=False, move_back=False, move=True, down_time=0.01, after_sleep=1) ``` 点击一个 `Box` 对象的相对位置。`box` 也可以传入 `Box` 列表(点击第一个)或预定义区域/特征名称字符串。 - **参数:** - `box` (Box | list[Box] | str): 要点击的 `Box` 对象、`Box` 列表(默认点击第一个)或可通过 `get_box_by_name` 找到的名称。 - `relative_x` (float): 相对于 `Box` 宽度的 x 坐标比例 (0.0 - 1.0)。 - `relative_y` (float): 相对于 `Box` 高度的 y 坐标比例 (0.0 - 1.0)。 - `raise_if_not_found` (bool): 如果 `box` 为 `None` 是否抛出异常。 - `move_back` (bool): 点击后是否将鼠标移回原位。 - `move` (bool): 是否在点击前移动鼠标。 - `down_time` (float): 鼠标按下的持续时间(秒)。 - `after_sleep` (float): 点击后等待的时间(秒);会调用 `sleep`,因此会清空当前缓存帧。 ### click\_box\_if\_name\_match ```python def click_box_if_name_match(self, boxes, names, relative_x=0.5, relative_y=0.5) ``` 在 `Box` 列表中查找名称匹配的 `Box` 并点击。匹配规则见 [名称匹配规则](#名称匹配规则-match--names)。 当 `names` 是列表时,列表越靠前优先级越高;如果多个框匹配,会返回并点击优先级最高的匹配项。 - **参数:** - `boxes` (list[Box]): `Box` 列表。 - `names` (str | re.Pattern | list[str | re.Pattern]): 要匹配的名称或正则模式,可以混用。 - `relative_x` (float): 相对于匹配 `Box` 宽度的 x 坐标比例。 - `relative_y` (float): 相对于匹配 `Box` 高度的 y 坐标比例。 - **返回:** - `Box` 或 `None`: 匹配并点击的 `Box`,未找到时返回 `None`。 ### click\_relative ```python def click_relative(self, x, y, move_back=False, hcenter=False, vcenter=False, move=True, after_sleep=0, name=None, interval=-1, down_time=0.02, key="left") ``` 在屏幕的相对位置执行点击。 - **参数:** - `x` (float): 相对于屏幕宽度的 x 坐标比例 (0.0 - 1.0)。 - `y` (float): 相对于屏幕高度的 y 坐标比例 (0.0 - 1.0)。 ### wait\_click\_box ```python def wait_click_box(self, condition, time_out=0, pre_action=None, post_action=None, raise_if_not_found=False) ``` 等待一个返回 `Box` 的条件函数成立,并点击该 `Box`。 - **参数:** - `condition` (callable): 返回 `Box` 或 `list[Box]` 的函数。 ### right\_click ```python def right_click(self, *args, **kwargs) ``` 执行鼠标右键点击。参数与 `click` 方法相同,但 `key` 固定为 'right'。 ### middle\_click ```python def middle_click(self, *args, **kwargs) ``` 执行鼠标中键点击。参数与 `click` 方法相同,但 `key` 固定为 'middle'。 ### swipe ```python def swipe(self, from_x, from_y, to_x, to_y, duration=0.5, after_sleep=0.1, settle_time=0) ``` 执行滑动操作。 - **参数:** - `from_x`, `from_y` (int): 滑动起点的绝对坐标。 - `to_x`, `to_y` (int): 滑动终点的绝对坐标。 - `duration` (float): 滑动持续时间(秒)。 - `after_sleep` (float): 滑动后等待的时间(秒);会调用 `sleep`,因此会清空当前缓存帧。 - `settle_time` (float): 到达终点后,在松开手指前停留的时间(秒)。 ### swipe\_relative ```python def swipe_relative(self, from_x, from_y, to_x, to_y, duration=0.5, settle_time=0) ``` 在屏幕的相对位置之间执行滑动操作。 - **参数:** - `from_x`, `from_y` (float): 滑动起点的相对坐标 (0.0 - 1.0)。 - `to_x`, `to_y` (float): 滑动终点的相对坐标 (0.0 - 1.0)。 ### input\_text ```python def input_text(self, text) ``` 输入指定的文本。 - **参数:** - `text` (str): 要输入的字符串。 ### send\_key ```python def send_key(self, key, down_time=0.02, interval=-1, after_sleep=0) ``` 模拟按下并释放一个键盘按键。 - **参数:** - `key` (str): 要发送的按键(例如 'a', 'enter', 'f1')。 ### send_key_down ```python def send_key_down(self, key, after_sleep=0) ``` 模拟按下键盘按键(不释放)。 ### send_key_up ```python def send_key_up(self, key, after_sleep=0) ``` 模拟释放键盘按键。 ### scroll ```python def scroll(self, x, y, count) ``` 在指定坐标位置执行鼠标滚轮滚动。 - **参数:** - `x`, `y` (int): 滚动的绝对坐标。 - `count` (int): 滚动量,正数向上,负数向下。 ### scroll\_relative ```python def scroll_relative(self, x, y, count) ``` 在屏幕的相对位置执行鼠标滚轮滚动。 - **参数:** - `x`, `y` (float): 滚动的相对坐标 (0.0 - 1.0)。 ### mouse\_down ```python def mouse_down(self, x=-1, y=-1, name=None, key="left") ``` 在指定位置按下鼠标按键(不释放)。 ### mouse\_up ```python def mouse_up(self, name=None, key="left") ``` 释放鼠标按键。 ### move ```python def move(self, x, y) ``` 将鼠标移动到指定的绝对坐标。 ### move\_relative ```python def move_relative(self, x, y) ``` 将鼠标移动到指定的相对坐标。 ### back ```python def back(self, *args, after_sleep=0, **kwargs) ``` 模拟返回操作,通常是发送 'esc' 键(PC)或返回键(Android)。支持 `after_sleep` 参数。 ### Config 相关 { #config-相关 } ### load\_config ```python def load_config(self) ``` 加载当前任务的配置文件。通常在任务初始化时自动调用。 ### validate\_config ```python def validate_config(self, key, value) ``` 验证一个配置项是否合法。子类可以重写此方法以实现自定义验证逻辑。 - **返回:** - `str` 或 `None`: 如果验证失败,返回错误信息字符串;否则返回 `None`。 ### get\_global\_config ```python def get_global_config(self, option) ``` 获取一个全局配置对象的值。 - **参数:** - `option` (ConfigOption): 全局配置选项的定义。 ### get\_global\_config\_desc ```python def get_global_config_desc(self, option) -> str ``` 获取一个全局配置选项的描述。 --- ### 任务配置 (Task Configuration) { #任务配置-task-configuration } `BaseTask` 允许通过 `default_config` 和 `config_type` 来定义任务在 GUI 界面中的配置表单。 #### 默认配置 (self.default_config) 在 `__init__` 中定义 `self.default_config`。框架会根据值的 Python 类型自动推断 GUI 控件: - `bool`: 开关按钮 (SwitchButton) - `int`: 整数输入框 (SpinBox) - `float`: 浮点数输入框 (DoubleSpinBox) - `list`: 列表修改项 (ModifyListItem) - 可通过 `config_type` 提供 `options_available` (list[str]),限制列表可添加的选项。 - 配合 `options_available` 使用 `allow_duplication` (bool, 默认 `False`) 时,可允许重复添加相同选项。 - `str`: - 长度 > 16 或包含 `\n`: 多行文本框 (TextEdit) - 其他情况: 单行文本框 (LineEdit) #### 显示指定配置类型 (self.config_type) 如果需要更复杂的控件(如下拉菜单、多选框或按钮),可以使用 `self.config_type` 进行显式定义。 `type` 是可选的;当配置项提供 `options` 时,会根据默认值自动推断为下拉框或多选框。 目前支持以下类型: - **`drop_down`**: 下拉选择框。 - **参数:** `options` (list[str]): 选项列表。 - **`multi_selection`**: 多选列表。 - **参数:** `options` (list[str]): 选项列表。 - **`text_edit`**: 强制使用多行文本框。 - **`file_selector`**: 文件或文件夹选择器。配置值必须是 `str`,界面会以只读文本显示当前值并提供按钮打开选择器。 - **参数:** `selector_type` (str, 可选): 选择器类型,`"file"` 或 `"folder"`,默认 `"file"`。 - **参数:** `dialog_title` (str, 可选): 选择器窗口标题。 - **参数:** `filter` (str, 可选): 文件选择器过滤器,例如 `"Images (*.png *.jpg);;All Files (*)"`,仅在 `selector_type` 为 `"file"` 时生效。 - **`global`**: 引用全局配置项。 - **`button` (NEW)**: 在配置区域显示一个或多个按钮,用于触发特定方法。 - **参数:** - `text` (str): 按钮上显示的文本(该文本会参与 `og.app.tr` 翻译)。 - `icon` (FluentIcon): 可选图标。 - `callback` (callable): 点击按钮时触发的函数或方法。 - `buttons` (list[dict]): 如果需要显示多个按钮,可以提供一个按钮配置列表,每个元素包含上述 `text`, `icon`, `callback`。 - **注意:** `button` 类型的配置项其 key 和 value 只用于 GUI 渲染展示,**不会** 被保存到本地配置文件中。 通用可选参数: - **`sub_configs`**: 可用于下拉选择框、布尔开关或多选列表,根据当前值控制其他配置项是否显示。key 是选项值或 `True`/`False`,value 是需要显示的配置项名称列表。对于多选列表,所有已选选项对应的配置项会按选项顺序合并,重复项只显示一次;未选择任何选项时,所有关联配置项都会隐藏。 **示例代码:** ```python class MyTask(BaseTask): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.default_config = { 'Run Count': 1, 'Mode': 'Default', 'Features': ['Logging'], 'Log Level': 'Info', 'Output Path': '', 'Input Path': '', 'Advanced Tool': 'Action' # 占位符 } self.config_type = { 'Mode': { 'options': ['Default', 'Fast'], 'sub_configs': { 'Fast': ['Advanced Tool'] } }, 'Features': { 'type': 'multi_selection', 'options': ['Logging', 'Export'], 'sub_configs': { 'Logging': ['Log Level'], 'Export': ['Output Path'] } }, 'Input Path': { 'type': 'file_selector', 'selector_type': 'folder', 'dialog_title': 'Select Input' }, 'Advanced Tool': { 'type': 'button', 'buttons': [ { 'text': 'Run Diagnosis', 'icon': FluentIcon.SEARCH, 'callback': self.run_diagnosis }, { 'text': 'Clean Cache', 'icon': FluentIcon.DELETE, 'callback': self.clean_cache } ] } } self.config_description = { 'Advanced Tool': 'Click to run advanced operations' } def run_diagnosis(self): self.log_info("Starting diagnosis...") ``` --- ### 屏幕画图 (Screen drawing) { #屏幕画图-screen-drawing } ### draw\_boxes ```python def draw_boxes(feature_name=None, boxes=None, color="red", debug=True) ``` 在屏幕上绘制一个或多个 `Box`,用于调试。 - **参数:** - `feature_name` (str, optional): 绘制的图层名称。 - `boxes` (list[Box] | Box): 要绘制的 `Box` 对象或列表。 ### clear\_box ```python def clear_box(self) ``` 清除屏幕上由 `draw_boxes` 绘制的所有框。 ### get\_overlay\_view ```python def get_overlay_view(self) ``` 返回覆盖在捕获窗口上的原始 Qt overlay widget。`BaseTask` 和 `CustomTab` 可直接调用此方法; 配置的 `my_app` 实例也会获得同名方法。无界面运行时返回 `None`。 任务线程需要通过 `overlay_view.draw(key, callback, duration=None)` 注册自定义绘制。回调会在 Qt 绘制线程中执行,参数为 `(painter, overlay_view)`,可使用 `QPainter` 绘制任意内容。存在 自定义绘制内容时 overlay 会自动显示,不受 `Enable Boxes` 开关影响。`duration` 为秒数;不传 时持续显示,直到调用 `overlay_view.clear_draw(key)` 或 `overlay_view.clear_draw()`: ```python from PySide6.QtGui import QColor, QFont, QPen from ok import TriggerTask class StatusOverlayTask(TriggerTask): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.default_config = {'_enabled': True} self.trigger_interval = 0.5 def run(self): overlay = self.get_overlay_view() if overlay is None: return status = "Tracking" def paint(painter, view): painter.setPen(QPen(QColor(0, 255, 120), 2)) painter.drawRect(30, 30, 240, 64) painter.setFont(QFont("Arial", 16)) painter.drawText(48, 70, status) overlay.draw("status", paint, duration=1) def on_destroy(self): overlay = self.get_overlay_view() if overlay is not None: overlay.clear_draw("status") ``` 应用配置可提供 `blur_area(width, height)` 回调,返回一个 `Box` 或 `list[Box]`,用于遮挡 游戏 UID 等静态区域: ```python from ok import Box def blur_area(width, height): return Box(width - 240, height - 42, 240, 42) config = { 'blur_area': blur_area, } ``` 配置后,基本设置中会出现 `Enable Blur` 开关,启用后可通过子配置 `Blur Algorithm` 选择 `Inpaint`(默认)或 `Blur`。`Inpaint` 会使用区域周围的像素重建内容,适用于从较简单背景上移除 UID。 开启时只在游戏窗口位于前台时显示处理后的区域;按 `Blur Interval` 检查变化,默认为 `1` 秒,设为 `0` 时每个 `next_frame` 均检查。保存截图时始终应用所选算法,与该开关无关。若还配置了 `screenshot_processor`,它会在处理完成后执行。调试面板中的 `Enable Boxes` 仅启用框绘制;overlay 只在有框、处理区域或自定义绘制内容需要显示时出现。 ### OCR ### ocr ```python def ocr(self, x=0, y=0, to_x=1, to_y=1, match=None, width=0, height=0, box=None, name=None, threshold=0, frame=None, target_height=0, use_grayscale=False, log=False, screenshot=False, frame_processor=None, lib='default') ``` 对屏幕指定区域进行光学字符识别(OCR)。如果不传 `match`,返回识别出的全部文本框;如果传了 `match`,只返回名称匹配的文本框。 - **参数:** - `x`, `y`, `to_x`, `to_y` (float): 识别区域的相对坐标;未传 `box` 时使用。 - `match` (str | re.Pattern | list[str | re.Pattern] | None): 用于过滤识别结果的名称匹配条件,见 [名称匹配规则](#名称匹配规则-match--names)。 - `width`, `height` (float): 识别区域的相对宽高;为 `0` 时使用 `to_x - x`、`to_y - y`。 - `box` (Box | str, optional): 指定一个 `Box` 或预定义区域/特征名称作为识别区域,优先级高于相对坐标。 - `name` (str, optional): 给识别区域命名,主要用于日志和调试绘制。 - `threshold` (float): OCR 结果的置信度阈值;为 `0` 时使用 `self.ocr_default_threshold`。 - `frame` (numpy.ndarray, optional): 指定图像帧;不传时使用当前屏幕帧。 - `target_height` (int): 识别前将图像缩放到的目标高度,可以提高识别准确率或速度。 - `use_grayscale` (bool): 识别前是否转为灰度图。 - `log` (bool): 是否输出 OCR 结果日志。 - `screenshot` (bool): 是否保存 OCR 调试截图。 - `frame_processor` (callable, optional): OCR 前对裁剪图像做自定义处理。 - `lib` (str): 使用 `config['ocr']` 中哪个 OCR 配置,默认 `"default"`。 - **返回:** - `list[Box]`: 包含识别结果的 `Box` 对象列表,`Box.name` 为识别出的文本。 ### wait\_ocr ```python def wait_ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, name=None, box=None, match=None, threshold=0, frame=None, target_height=0, time_out=0, post_action=None, raise_if_not_found=False, log=False, screenshot=False, settle_time=-1, lib="default") ``` 等待直到在指定区域内 OCR 识别到文本。大多数参数与 `ocr` 相同;`match` 支持字符串、正则以及两者混合列表,见 [名称匹配规则](#名称匹配规则-match--names)。 - **返回:** - `list[Box]` 或 `None`: 找到的文本 `Box` 列表;超时且未抛异常时返回 `None`。 ### wait\_click\_ocr ```python def wait_click_ocr(self, x=0, y=0, to_x=1, to_y=1, width=0, height=0, box=None, name=None, match=None, threshold=0, frame=None, target_height=0, time_out=0, raise_if_not_found=False, recheck_time=0, after_sleep=0, post_action=None, log=False, screenshot=False, settle_time=-1, lib="default") ``` 等待直到 OCR 识别到匹配的文本,并点击找到的结果中的第一个框。参数与 `ocr` 类似;`recheck_time > 0` 时会在等待命中后短暂等待并再 OCR 一次。 - **返回:** - `list[Box]` 或 `None`: 被点击前得到的 OCR `Box` 列表;未找到时返回 `None`。 ### add\_text\_fix ```python def add_text_fix(self, fix) ``` 添加 OCR 文本修正规则。用于修正 OCR 引擎常见的识别错误。 - **参数:** - `fix` (dict): 一个字典,键为错误文本,值为正确文本。 ### 找图 (Image finding) { #找图-image-finding } ### find\_feature ```python def find_feature(self, feature_name=None, horizontal_variance=0, vertical_variance=0, threshold=0, use_gray_scale=False, x=-1, y=-1, to_x=-1, to_y=-1, width=-1, height=-1, box=None, canny_lower=0, canny_higher=0, frame_processor=None, template=None, match_method=cv2.TM_CCOEFF_NORMED, screenshot=False, mask_function=None, frame=None, limit=0, target_height=0) -> List[Box] ``` 在指定区域内查找一个或多个图像特征。 - **参数:** - `feature_name` (str | list[str]): 要查找的特征名称。 - `box` (Box | str, optional): 在该 `Box` 区域内进行搜索;字符串会通过 `get_box_by_name` 转为区域。 - `threshold` (float): 匹配的置信度阈值。 - `limit` (int): 限制返回数量;`0` 表示不限制。 - `frame` (numpy.ndarray, optional): 指定搜索帧;不传时使用当前屏幕帧。 - **返回:** - `list[Box]`: 找到的所有匹配特征的 `Box` 对象列表。 ### find\_one ```python def find_one(self, feature_name=None, horizontal_variance=0, vertical_variance=0, threshold=0, use_gray_scale=False, box=None, canny_lower=0, canny_higher=0, frame_processor=None, template=None, mask_function=None, frame=None, match_method=cv2.TM_CCOEFF_NORMED, screenshot=False, limit=1, target_height=0) -> Box ``` 查找单个图像特征,并返回置信度最高的一个。参数与 `find_feature` 相同。 - **返回:** - `Box` 或 `None`: 找到的置信度最高的 `Box` 对象,如果未找到则返回 `None`。 ### wait\_feature ```python def wait_feature(self, feature, horizontal_variance=0, vertical_variance=0, threshold=0, time_out=0, pre_action=None, post_action=None, use_gray_scale=False, box=None, raise_if_not_found=False, canny_lower=0, canny_higher=0, settle_time=-1, frame_processor=None, target_height=0) ``` 等待直到在屏幕上找到指定的图像特征。 - **参数:** - `feature` (str): 要等待的特征名称。 - `time_out` (int): 等待的超时时间(秒)。 - **返回:** - `Box` 或 `None`: 找到的 `Box` 对象。 ### wait\_click\_feature ```python def wait_click_feature(self, feature, horizontal_variance=0, vertical_variance=0, threshold=0, relative_x=0.5, relative_y=0.5, time_out=0, pre_action=None, post_action=None, box=None, raise_if_not_found=True, use_gray_scale=False, canny_lower=0, canny_higher=0, click_after_delay=0, settle_time=-1, after_sleep=0, target_height=0) ``` 等待直到找到指定的图像特征,并对其进行点击。 - **返回:** - `bool`: 如果成功找到并点击,返回 `True`。 ### get\_box\_by\_name ```python def get_box_by_name(self, name) -> Box ``` 根据名称获取一个预定义的 `Box`。名称可以是定义的特征名,也可以是内置预设区域。 - **可选预设名称:** - `full_screen` - `top`, `bottom`, `left`, `right` - `top_left`, `top_right`, `bottom_left`, `bottom_right` - **返回:** - `Box`: 对应的 `Box` 对象。 ### get\_feature\_by\_name ```python def get_feature_by_name(self, name) ``` 根据名称获取特性的详细定义和原始图像。 ### feature\_exists ```python def feature_exists(self, feature_name: str) -> bool ``` 检查指定的特征名称是否在已加载的任务特征集中。 ### find\_feature\_and\_set ```python def find_feature_and_set(self, features, horizontal_variance=0, vertical_variance=0, threshold=0) -> bool ``` 查找多个特征并将结果作为同名属性设置到当前任务对象中。 - **参数:** - `features` (str | list[str]): 要查找的特征名称。 - **返回:** - `bool`: 是否所有指定的特征都找到了。 ### find\_best\_match\_in\_box ```python def find_best_match_in_box(self, box, to_find, threshold, use_gray_scale=False, canny_lower=0, canny_higher=0, frame_processor=None, mask_function=None) -> Box ``` 在给定的 `Box` 内寻找 `to_find` 列表中置信度最高的一个特征。`to_find` 应为特征名称列表。 ### find\_first\_match\_in\_box ```python def find_first_match_in_box(self, box, to_find, threshold, use_gray_scale=False, canny_lower=0, canny_higher=0, frame_processor=None, mask_function=None) -> Box ``` 在给定的 `Box` 内按 `to_find` 顺序查找,第一个找到的特征会被立即返回。 ### 找色 (Color finding) { #找色-color-finding } ### calculate\_color\_percentage ```python def calculate_color_percentage(self, color, box: Box | str) -> float ``` 计算指定 `Box` 区域内特定颜色的像素百分比。 - **参数:** - `color` (dict): 颜色范围字典,格式为 `{'r': (min, max), 'g': (min, max), 'b': (min, max)}`。 - `box` (Box | str): 要计算的 `Box` 对象或其名称。 - **返回:** - `float`: 颜色像素所占的百分比 (0.0 - 1.0)。 ### 显示信息 (Display information) { #显示信息-display-information } ### notification ```python def notification(self, message, title=None, error=False, tray=False, show_tab=None, params=None, images=None, screenshot=False) ``` 在主界面显示一个通知信息条或系统托盘通知。 - **参数:** - `message` (str): 通知内容。 - `tray` (bool): 是否同时显示系统托盘通知。 - `show_tab` (str): 点击通知时跳转到的 UI 选项卡。 - `params` (any): 随通知一起传递给 UI 的附加参数。 - `images` (numpy.ndarray | list[numpy.ndarray] | None): 可选的单张或多张 OpenCV 图像。图像会异步写入 `screenshots/notification`,并发送给支持图像的通知服务,但不会显示在应用界面中。 - `screenshot` (bool): 为 `True` 时,将当前帧追加到 `images`。默认为 `False`。 ### info\_set ```python def info_set(self, key, value) ``` 在任务的监控信息中设置一个键值对(会显示在 UI 的任务卡片中)。 ### info\_get ```python def info_get(self, key, default=None) ``` 从任务的监控信息中获取一个值。 ### info\_incr ```python def info_incr(self, key, inc=1) ``` 增加监控信息中的数值。 ### info\_add ```python def info_add(self, key, count=1) ``` 同 `info_incr`。 ### info\_add\_to\_list ```python def info_add_to_list(self, key, item) ``` 将一个项添加到监控信息中的列表(如果键不存在则创建列表)。 ### info\_clear ```python def info_clear(self) ``` 清除当前任务的所有监控信息。 ### 日志 (Logging) { #日志-logging } ### log\_info ```python def log_info(self, message, notify=False, images=None, screenshot=False) ``` 记录一条信息级别的日志。可选图像和当前帧会异步写入 `screenshots/log`。 ### log\_debug ```python def log_debug(self, message, notify=False, images=None, screenshot=False) ``` 记录一条调试级别的日志。可选图像和当前帧会异步写入 `screenshots/log`。 ### log\_error ```python def log_error(self, message, exception=None, notify=False, images=None, screenshot=False) ``` 记录一条错误级别的日志。无论 `screenshot` 的值为何,都会保存当前帧。 ### 其他 (Other) { #其他-other } ### is\_adb ```python def is_adb(self) -> bool ``` 判断当前是否连接的是 ADB 设备(安卓/模拟器)。 ### is\_browser ```python def is_browser(self) -> bool ``` 判断当前是否正在控制浏览器设备。 ### adb\_shell ```python def adb_shell(self, *args, **kwargs) -> str ``` 执行一条 ADB shell 指令并返回输出字符串。 ### ensure\_in\_front ```python def ensure_in_front(self) ``` 确保游戏窗口或 ADB 模拟器处于前台显示状态。只有目标应用或游戏必须在前台才能接收输入时,才需要主动调用此方法;大部分支持后台输入的设备或窗口交互方式不需要调用。 ### box\_of\_screen ```python def box_of_screen(self, x, y, to_x=1.0, to_y=1.0, width=0.0, height=0.0, name=None, hcenter=False, vcenter=False, confidence=1.0) -> Box ``` 根据相对比例创建一个相对于当前屏幕尺寸的 `Box` 对象。 - **参数:** - `x`, `y` (float): 相对于屏幕的相对坐标 (0.0 - 1.0)。 - `to_x`, `to_y` (float): 右下角相对坐标;未显式指定 `width`/`height` 时用于计算大小。 - `width`, `height` (float): 相对宽高;为 `0` 时根据 `to_x`/`to_y` 计算。 - `name` (str, optional): 生成的 `Box` 名称。 - `hcenter`, `vcenter` (bool): 在非标准屏幕比例下按水平/垂直居中规则缩放坐标。 - `confidence` (float): 写入返回 `Box.confidence` 的置信度。 ### box\_of\_screen\_scaled ```python def box_of_screen_scaled(self, original_screen_width, original_screen_height, x_original, y_original, to_x=0, to_y=0, width_original=0, height_original=0, name=None, hcenter=False, vcenter=False, confidence=1.0) -> Box ``` 根据原始参考屏幕的分辨率,将坐标缩放到当前屏幕分辨率并创建一个 `Box`。 ### screen\_width ```python @property def screen_width(self) -> int ``` 获取当前屏幕的像素宽度。 ### screen\_height ```python @property def screen_height(self) -> int ``` 获取当前屏幕的像素高度。 ### width\_of\_screen ```python def width_of_screen(self, percent) -> int ``` 根据传入的百分比计算并返回对应的屏幕像素宽度。 ### wait\_until ```python def wait_until(self, condition, time_out=0, pre_action=None, post_action=None, settle_time=-1, raise_if_not_found=False) ``` 等待直到 `condition` 函数返回一个真值(或非空值)。 - **参数:** - `condition` (callable): 无参数的可调用函数。 - `time_out` (int): 超时时间(秒),0 表示无限等待。 ### wait\_scene ```python def wait_scene(self, scene_type=None, time_out=0, pre_action=None, post_action=None) ``` 等待当前场景变为指定的 `scene_type`。 ### sleep ```python def sleep(self, timeout) ``` 让当前任务休眠指定秒数。调用时会重置场景并清空当前缓存帧;休眠期间会处理脚本暂停和 `sleep_check`。 如果刚执行了会改变界面的操作,常用 `sleep(0.5)` 等待界面稳定后再读取新的 `frame`;如果使用 `wait_` 开头的方法,则通常不需要在调用前手动 `sleep`。 ### sleep\_check ```python def sleep_check(self) ``` 当脚本休眠时,若设置了 `sleep_check_interval`,会定期调用此方法执行背景检查逻辑。 ### run\_task\_by\_class ```python def run_task_by_class(self, cls) ``` 在当前任务上下文中实例化并运行指定的另一个任务类。 ### tr ```python def tr(self, message) -> str ``` 翻译指定的字符串消息(使用应用级的 i18n 系统)。 ### should\_trigger ```python def should_trigger(self) -> bool ``` 根据配置的 `trigger_interval` 判断当前是否应该触发任务执行。 ### go\_to\_tab ```python def go_to_tab(self, tab) ``` 通知 UI 界面跳转到指定的选项卡。 ### find\_boxes ```python def find_boxes(self, boxes, match=None, boundary=None) -> list[Box] ``` 对 `Box` 列表进行过滤,支持名称匹配和边界筛选。 - **参数:** - `boxes` (list[Box]): 待过滤的 `Box` 列表。 - `match` (str | re.Pattern | list[str | re.Pattern] | None): 名称匹配条件,见 [名称匹配规则](#名称匹配规则-match--names)。 - `boundary` (Box | str | None): 只保留完全位于该边界内的 `Box`;字符串会通过 `get_box_by_name` 转为边界。 - **返回:** - `list[Box]`: 过滤后的 `Box` 列表。