本文是sikuli tutorials中文翻译,原文请看:http://doc.sikuli.org/tutorials/index.html

Hello World

让我们从一个习惯性的Hello World示例开始!您将学习如何捕获GUI元素的屏幕截图并编写Sikuli脚本来完成两件事:

  1. 单击该元素
  2. 在该元素中键入字符串​

Hello World脚本的目标是在“开始”菜单搜索框中自动键入“Hello World”,如下所示:

Sikuli教程_sikuli

打开Sikuli IDE。我们首先拍摄目标的屏幕截图,开始菜单符号通常位于桌面的左下角。使用这个屏幕截图,我们可以告诉Sikuli脚本单击什么。

要模拟鼠标单击开始符号,我们将使用单击功能。为了告诉Sikuli开始符号的样子,我们需要在屏幕上捕捉它的图像。

Sikuli IDE提供了两种捕获屏幕图像的方法。第一种方法是单击工具栏中的“摄影机”按钮。这将使您进入屏幕捕获模式。

Sikuli教程_图像识别_02

第二种方法是按热键(Ctrl+Shift+2)。通常,希望捕获其图像的目标可能会被Sikuli IDE的窗口覆盖。您可以最小化IDE窗口,并使用此热键切换到捕获模式。

在屏幕捕获模式下,屏幕将变暗并暂时冻结。整个桌面就像一块画布,在那里你可以围绕你想要捕捉的目标画一个矩形。在这种情况下,目标是开始符号。红色虚线的十字表示您刚才绘制的矩形的中心。

Sikuli教程_图像识别_03

绘制(或选择)矩形后,将捕获矩形内的图像并将其插入脚本编辑器中当前光标位置。

Sikuli教程_图像识别_04

现在,您可以使用此图像作为参数编写单击函数,以告诉Sikuli单击开始符号。

Sikuli教程_AI_05

为了方便起见,Sikuli IDE在左侧面板上提供了一个命令列表。它显示了最常用函数的列表。函数中的相机图标表示这些函数期望捕获的图像作为参数。

Sikuli教程_AI_06

在列表中找到click()函数并单击它。如果“自动捕获”处于启用状态(默认),您将被引导到屏幕捕获模式,在此模式下,您可以捕获要作为参数插入click()函数的接口目标的图像。

下一步是告诉Sikuli在搜索框中输入字符串“Hello World”,这可以通过一个简单的类型函数完成。

此函数将参数中给定的字符串键入具有焦点的输入控件中。单击开始符号后,我们可以预期搜索框将是具有焦点的输入。

祝贺您刚刚完成了第一个Sikuli脚本。按run按钮查看此脚本的运行情况!

取消复选框

在本教程中,我们将演示如何使用for循环与GUI组件的多个实例交互。假设我们要取消选中窗口中的所有复选框,例如下面显示的共享首选项窗口:

Sikuli教程_python_07

不幸的是,没有“全部取消选中”功能可用。解决方案是什么?编写一个Sikuli脚本来查找所有选中的项目并自动取消选中它们。此操作所需的函数是findAll()。

首先,让我们捕获选中项目的屏幕截图图像。

Sikuli教程_sikuli_08

然后,我们可以将图像插入findAll()函数。

Sikuli教程_sikuli_09

findAll()在整个屏幕上搜索所有匹配的视觉模式,并返回这些相似模式的位置列表。此功能允许我们获取屏幕上的所有选中项目。然后,我们可以简单地用标准Python语法编写一个for循环,并对列表中的每个元素调用click()。

Sikuli教程_AI_10

执行此脚本时,Sikuli将找到当前选中的所有项目,并在循环中逐个单击每个项目。

选中复选框

本教程演示如何在窗口中有多个复选框时选中特定复选框。考虑下面的窗口,它是设置Mac上的BooT首选项的窗口,我们要检查循环指示的“复选框”,它将“最小化窗口插入应用程序图标”。

Sikuli教程_自动化_11

简单地查找如下复选框的图像将不起作用。

Sikuli教程_python_12

Sikuli不知道我们指的是哪个复选框;它只需点击找到的第一个。下面是我们将要做的。

首先,我们希望获得Dock窗格内容区域的覆盖区域。实现这一点的一种方法是使用空间操作符获取停靠窗格标题栏下方的区域。下图说明了这一策略。

Sikuli教程_自动化_13

执行此操作的Sikuli脚本是:

Sikuli教程_python_14

它找到标题栏,然后使用下面的空间操作符将匹配区域扩展到300像素以下。结果区域被分配给变量r,即上图中的橙色矩形。

接下来,我们可以在内容区域r中搜索要检查的复选框的标签文本,然后单击它。

Sikuli教程_自动化_15

如果我们点击(t),Sikuli将点击标签的中心。但是,我们要做的是单击标签右侧的复选框。

Sikuli IDE提供了一个方便的界面,用于指定相对于图案中心单击的位置。这称为目标偏移。界面如下所示。

Sikuli教程_自动化_16

在这个界面中,我们可以单击复选框来指示所需的单击点位置。在此示例中,偏移量随后被确定为-137 In x,这意味着文本标签中心左侧137个像素。选择偏移后,脚本编辑器中的缩略图将更新为一个小红十字,以指示新的单击点。

Sikuli教程_自动化_17

然后,调用click(t)将做正确的事情,单击复选框而不是文本标签的中心。

使用滑块

在本教程中,我们将通过编写大量脚本来操作滑块,学习如何使用dragDrop()和空间运算符。

假设我们希望降低文本到语音功能的说话速率。我们想在下面显示的Speech preferences窗口中将滑块拖动到慢速侧。

Sikuli教程_自动化_18

可以执行拖动的函数是dragDrop()。此函数将两个图像作为参数。第一个图像描述了要拖动的源GUI对象,第二个图像描述了GUI对象应该被拖动到和拖放到的目标位置的外观。

让我们分别捕获源图像和目标图像。

Sikuli教程_图像识别_19

如果有两个以上的滑块,会发生什么情况。如何确保拖动了正确的滑块?上面的示例之所以有效,是因为特定窗口只有一个滑块。当存在多个外观相似的GUI组件实例时,我们如何处理这种情况?让我们考虑下面的声音偏好窗口。

Sikuli教程_python_20

假设我们希望降低警报音量。为了确保Sikuli脚本拖动右侧滑块,我们需要一种方法来告诉Sikuli脚本查找警报卷标右侧的滑块,而不是输出卷标旁边的滑块。Sikuli脚本提供了一组空间操作符来实现这一点。这里我们将应用right()操作符,如下所示。

Sikuli教程_AI_21

此语句告诉Sikuli脚本首先查找警报卷标,然后仅在第一次查找结果右侧的区域内查找滑块拇指。找到的滑块拇指随后存储在变量t中。现在我们已经确定了所需的滑块拇指,我们可以调用dragDrop()将其向左拖动,方法是将Alter volume的图像作为目标。

Sikuli教程_sikuli_22

在上面的示例中,我们使用警报卷标的图像隐式引导向左拖动的方向。也可以使用相对坐标显式向左拖动,如下所示。

Sikuli教程_图像识别_23

这里,滑块拇指的(x,y)坐标可以作为t的属性访问。因此,我们可以计算t左侧200像素的位置,并要求Sikuli脚本将拇指拖动到该位置。

桌面监视

Sikuli脚本可用于执行桌面监视。在本教程中,我们将通过一些练习来创建脚本,这些脚本可以监视屏幕,并在发生某些有趣的视觉事件时通知我们。

Facebook App

第一个练习是创建一个Facebook应用程序,定期查看我们的Facebook主页,看看某个朋友最近是否更新了状态消息。检测此事件的一个简单方法是在我们的Facebook主页上查找朋友的面部图像。如果找到,则该朋友必须已发布新的状态消息。如果没有找到,我们应该在几分钟后再次检查。

让我们使用while:loop实现这个操作。首先,我们需要捕捉一张朋友的面部图像截图。


为了检查是否可以在屏幕上看到朋友的脸,我们使用exists(),当找到人脸图像时,它返回True。我们将循环条件设置为Not Found,以便while循环仅在找到人脸图像时终止。我们在循环体中添加了一个sleep(n)语句,以在尝试在屏幕上查找人脸图像之间引入5秒的间隔。


或者,Sikuli提供了一个方便的wait()函数,定期检查屏幕,等待给定的图像模式出现。使用wait(),上述代码可以重写为:


永久不变意味着我们希望Sikuli无限期地等待。如果我们不想永远等待,我们可以用一个数字来代替“永远”,以表示等待Sikuli应该放弃的秒数。


当while循环退出或wait函数返回后,我们可以调用popup()来显示通知消息。

Sikuli教程_自动化_24

这将显示一条弹出消息,如下所示:

Sikuli教程_python_25

现在,我们可以运行这个Sikuli Facebook应用程序,坐下来放松一下,当我们的朋友更新他的消息时,我们会得到通知。

Skype App

在上一个练习中,我们编写了一个脚本来检测图像的外观。在本练习中,我们将执行相反的操作—检测视觉模式的消失。

Skype是一个很好的工具,它使我们能够与朋友保持密切联系,即使他们在世界的偏远地区。然而,在某些不幸的情况下,我们可能希望避免被某个人在网上看到。也许这个人说得太多了。也许我们欠个人一些钱。如果你能知道这个人什么时候离线就好了,这样你就可以安全地上网了。虽然Skype确实提供了一种功能,可以在个人在线时通知我们,但当出现相反情况时,却没有通知功能。

需要一个自动注销通知程序来处理这种情况。让我们使用Sikuli脚本构建此工具。请注意,如果个人不再在线,则绿色状态图标和个人屏幕名称的组合视觉模式将消失。因此,我们可以拍摄一个包含绿色图标和屏幕名称的屏幕截图,如下所示。

Sikuli教程_AI_26

然后,我们可以写一个Sikuli脚本来观察我们刚刚捕获的截图图像的消失。

Sikuli教程_自动化_27

此脚本与上一个练习中的脚本非常相似。唯一的区别是从while循环的条件语句中删除NOT操作符,因为我们正试图做相反的事情。

等待图像消失的另一种方法是使用waitVanish()函数。上述脚本可以重写如下:

Sikuli教程_python_28

Bus Arrival Notifier​

第三个练习是构建公交车到达通知工具。对于许多公交车乘客来说,基于GPS的在线跟踪服务非常有用。骑手们可以舒适地坐在车内的电脑前,查看电子邮件、更新Facebook状态或观看YouTube,而不是耐心地站在停车场外,冒着冬天的寒风或夏天的烈日?视频,或者你有什么。他们只需每隔几分钟查看一次地图,就可以查看巴士标志在地图上的位置。只有当公共汽车足够近的时候,他们才能最终下车,步行到公共汽车的顶部。

因为我们关心公共汽车是否接近车站,所以我们只需要看看车站周围的邻居。因此,我们可以调整浏览器的大小,只显示地图的这一部分,同时留下大量屏幕空间来做其他事情,在本例中,阅读CNN新闻。

Sikuli教程_sikuli_29

让我们写一个Sikuli脚本来为我们跟踪巴士。可以定义一个区域,并要求Sikuli脚本仅关注该区域以搜索特定的视觉模式。这样,Sikuli就不必浪费宝贵的计算周期来扫描整个屏幕。为此,让我们单击工具栏中的“选择区域”按钮,如下所示。

Sikuli教程_sikuli_30

整个屏幕将冻结并变暗,类似于屏幕捕获模式下发生的情况。只需画一个矩形覆盖整个邻域地图。该矩形覆盖的区域可视为整个桌面的缩略图,该区域以红色着色。

Sikuli教程_sikuli_31

接下来,我们捕获巴士符号的屏幕截图图像,以便告诉Sikuli脚本注意其外观。

Sikuli教程_图像识别_32

现在我们可以编写以下脚本来检查地图并观察总线符号的外观:

Sikuli教程_sikuli_33

解释while循环的含义很简单,但在区域内找不到总线符号的情况下,休眠5秒。换句话说,while循环只有在区域内找到总线符号时才会退出。然后,将执行弹出语句来通知我们总线已到达。

同样,使用wait()也可以达到同样的效果。脚本可以重写为

Sikuli教程_sikuli_34

调整窗口大小

本教程演示如何使用Sikuli脚本通过拖动窗口的右下角来调整窗口大小。为此,您必须计算屏幕上此角的当前位置,将鼠标指针移动到相应的单击点,然后执行一个或多个拖动操作。

Sikuli教程_图像识别_35

本例定义了一个函数“resizeApp”,用于放大Mac上的窗口,然后调用该函数将Safari的大小放大50x50像素。有几种方法可以完成这项任务。最简单的方法是直接查找角点并拖动它以放大窗口。

除了这个最简单的方法之外,我们还想向您展示做同样事情的更多可能的方法。以下示例演示如何使用空间运算符扩展或限制搜索区域。

找到此角点的方法是首先确定窗口最具特征的角点(主要是带有窗口按钮的角点),然后尝试查找其他相关角点,以确保获得所需的点击点。该战略如下所示。我们要找到右上角,然后向右找到右上角,然后向下找到右下角。

Sikuli教程_sikuli_36

实现此计划的脚本可以编写如下:

Sikuli教程_自动化_37

工作流和鼠标移动到单击点可以压缩为一行(在本例中不检查标题)。

Sikuli教程_自动化_38

一般性意见:

  • 只要有可能,查找操作都被限制在一个区域内,该区域应包含相关匹配项,以将发现其他内容的风险降至最低。最重要的是,这加快了速度。
  • 这个例子可以很容易地转换成一个辅助函数,其中所有图像和变量都可以作为参数给出。
  • 单击点是在IDE中使用预览窗口进行评估的,但为了灵活性和可读性,需要将其放入代码中。
  • 使用了低级鼠标功能,因此您可以更灵活地连续移动。
  • 开发方法是,首先运行所有东西来评估相关的角落。在这个阶段,带有“#debug”的注释都没有注释,以获得一些反馈。特别是setShowActions()和exit()非常有用。