2010年12月29日星期三

Sikuli X 之 Region类相关说明

PSMRL:指可以把模式(Pattern)、指向图像文件名的字符串或者表示纯文本的字符串(string )、匹配(Match)、区域(Region)或者位置(Location)作为参数进行传递。

PS:指可以把模式(Pattern)、指向图像文件名的字符串或者表示纯文本的字符串(string )作为参数进行传递。

applicable for Screen or Match or Screen and Match:尽管区域(Region)的所有方法可以用于显示器(Screen)类和匹配(Match)类的对象上,但是每个方法在这些类上都是合理的(例如:Screen(0).below(),find(PS).setRect(rectangle))。所以,如果提及它,就表示在应用场景中这个方法在屏幕对象或者匹配对象上使用是合理的。

Note on Multi Monitor Environments:在多于一个显示器被激活的情况下,想要对非默认屏幕(这种情况下是主显示器)上的区域进行操作,要考虑一些特殊因素。所以,在多于一个显示器的环境下开始使用Sikuli之前,要先阅读多显示器环境相关章节。

2010年12月28日星期二

Qt单实例运行

程序要求单实例运行,且如果第二次运行激活已存在的程序实例的窗口。
于是有了下面的这段代码。

QSystemSemaphore sema("sema", 1, QSystemSemaphore::Open);
sema.acquire();
QSharedMemory mem("memObject");
if (!mem.create(1)) {
HWND w = FindWindow(NULL, "Window Title");
if (w)
{
SetForegroundWindow(w);
ShowWindow(w, SW_SHOWNORMAL);
}
sema.release();
return 0;
}
sema.release();

神奇的是的Qt里,只写ShowWindow是不行的,如果窗口最小化后再从另一个实例中激活它,窗口上的控件得不到绘制。可能是Qt的消息处理函数进行了判断吧。而且必须得在ShowWindow之前调用SetForegroudWindow。

2010年12月24日星期五

Sikuli X 之 Region类

区域(Region)就是屏幕上的一个矩形部分,它由位置和维度确定。位置 (x, y) 就是它的左上角相对于屏幕左上角的距离;维度 (w, h) 就是它的宽和高。
其中 x、y、w、h是以像素为单位计算距离的整数值。

区域(Region)只知道它在屏幕上的位置和它的维度,并不知道任何它的可视内容(窗体、图片、图形、文本等)。

新的区域(Region)可以在已有的区域基础上创建:你可以在各个方向上扩展区域或者获取相信区域,直到屏幕的水平或者垂直边界。

区域(Region)上的可视内容和文本内容可以使用像find()这样的方法计算得到,find()方法在区域搜索一个给定的矩形像素模式或者文本串。区域中进行匹配的内容有一个在0到1之间的相似度,0就是没有找到,1就是找到了且它的每一个像素都与模式精确匹配。可以让find以一个最小的相似度进行搜索,这样一些形状和颜色的微小变化就可以被忽略。如果不指定其他东西,Sikuli将以最小相似度0.7进行搜索,通常的情况下这样做与预期相符。

查找(Find)操作返回一个匹配(Match),它具有一个区域(Region)拥有的所有属性和方法,可以以相同的方式使用(比如查找或点击它里面的另一个目标)。匹配(Match)包含了搜索中使用的模式的维度,它也知道模式被发现的位置以及相似度。有一个区域保存了最后一次成功的查找操作中最佳的匹配和最后一次成功的findAll()返回的所有匹配(通过getLastMatch()/getLastMatches()获取)。你可以使用wait()等待模式出现,使用waitVanish()等待模式消失,或者只是使用exists()检查一下模式是否存在,这样就不用处理异常(当模式不存在的时候,exists()返回None,而不是抛出异常)。

Sikuli X支持可视化事件驱动编程。你可以告诉一个区域来观察某些东西的出现、消失或变化。这就有可以等待一个观察结果的完成或者让它在后台运行,而你的脚本继续执行。当这些可视化事件发生时,你脚本中的处理器就会被调用。每个区域有一个观察者,每个观察者可以处理多个可视化事件。停止观察是你的责任。

你可以通过模拟鼠标和键盘行为在一个区域上操作。你可以选择在先前查找操作中计算出的区块内操作,也可以一个将被隐含查找的模式上操作。要想模拟像游戏或者图形这样的特殊应用程序中的复杂操作,有低级的鼠标和键盘操作可用。

想支持更复杂和健壮的脚本,你可以处理FindFailed异常,当查找操作失败会将会抛出它。

在同一个区域上的操作,可以使用Python的"with"语句进行分组。

Screen是继承了Region类的所有属性和访求的另一个类。通过Screen类,你可以获取屏幕维度和不同的显示器(如果你有多个显示器)。如果你不指定区域,它也给了你一个默认的区域来操作。通常在你对整个屏幕进行搜索的时候,仍需要写region.find(image),只是这里的region是整个屏幕。所以为了方便,如果只写find(image)将简单的在整个屏幕中操作(实际上是默认/主要的屏幕),而不用每次都指定默认的SCREEN。而另一面,这样做将降低搜索速度,因为在整个屏幕上查找目标是耗时的。所以,为了提升处理速度,写region.find()能把搜索限定在指定的更小的矩形内(通常是你感兴趣的应该程序的主窗体)。另外,可以使用setROI()把随后的查找操作在比整个屏幕更小的区域中。

2010年12月21日星期二

Why X? eXperimental

Sikuli X要来了,一直纳闷为什么要改成X呢,今天到LaunchPad上一逛,原来X stands for eXperimental。难道以后就这样一直eXperimental下去,一直X下去了?不管如何,准备开始跟踪这个X了。

看了Sikuli的文档,全局函数里只有几个打开关闭应用程序的函数,可是平时写代码的时候都是直接find,click的啊,难道它们不是全局函数?果然,它们都是Region对象的函数,当不指定对象直接使用这些函数的时候,默认的对象是Screen,当然,Screen类是继承自Region类的。看来就从这个重要的Region类开始吧。


2010年12月17日星期五

够酷够强的Sikuli

又见 Sikuli。自从Sikuli刚刚出来时,简单用了下,发现它真是够酷够简,后来没有再用到也就没继续关注了。现在偶然又看见了Sikuli的身影,真是够酷够强了。不仅很久以前就已经有了一些OCR的功能,而且整个IDE也更加完整了,还提供了UnitTest框架,看来确实想在界面自动化测试方面大展身手了。

再看看预告中的Sikuli X,首先是要加入文本的识别与匹配,这一功能不仅可以简化脚本的编写,对于一些文本界面元素,直接在脚本中输入文字不必非得去屏幕取图了,而且对于脚本中对目标程序的控制也更加方便,可以读取并处理界面中的文本了。此外,Sikuli脚本将允许使用import语句重用,这样就有可能通过编写不同层次的Sikuli脚本以形成一个产品的测试框架。还有就是Sikuli将会把操作限制在目标程序的窗口范围之内,这样应该可以提高效率与准确性。

仍是简单试用了一下,发现对双显示器的支持还是不够,目标程序放在主显示器,Sikuli可以匹配到目标,操作的时候却把鼠标移到了次显示器的相应坐标处。期待能在Sikuli X中解决这问题。也许Sikuli X把操作限制在目标程序 窗口范围之内的功能有助于这个问题的解决。