上期回顾:Poco框架源码目录结构解析


以下基于
python3.8;airtestIDE1.2.13;airtest1.2.4;pocoui1.0.85

前两期我们讲了Poco API,会发现和Airtest API有很多同名,但是使用方法却不一样。导致不一样的原因就是Airtest和Poco使用了不同的坐标系,今天我们就来详细看下两者具体的不同。

Airtest是基于图片识别的框架,讲究所见即所得,所以其坐标都是使用的屏幕绝对坐标,如:
touch([500,500])
swipe([100,100],[500,500])
假如手机屏幕就是1000*1000,[500,500]就是屏幕的中心点,屏幕绝对坐标很好理解,这里就不多讲了。

Poco是基于控件元素的框架,为了跨分辨率适配,使用‘归一化坐标系’和‘局部坐标系’。

归一化坐标系(Normalized Coordinate System)

什么是‘归一化坐标系’,就是将屏幕宽和高按照单位一来算,这样UI在poco中的宽和高其实就是相对于屏幕的百分比大小了,好处就是不同分辨率设备之间,同一个UI的归一化坐标系下的位置和尺寸是一样的,有助于代码跨分辨率执行,举个例子:

在airtest中左右滑动屏幕的代码 airtest点击坐标_在airtest中左右滑动屏幕的代码

 

 

假如图中左右是两个手机屏幕,一个是100*100,一个是200*200。小手机左上有个按钮,其中心点绝对坐标是[25,25],那么这个点相对于整个屏幕百分比大小就是[25/100,25/100]=[0.25,0.25]
同理,大手机左上按钮的中心点绝对坐标是[50,50],那么这个点相对于整个屏幕百分比大小就是[50/200,50/200]=[0.25,0.25]

所以同一APP运行在这2个手机上,我们想利用坐标点击左上的按钮,如果用Airtest框架就要分别写成
touch([25,25]) 和 touch([50,50])

而如果是用Poco框架,则只要写成

from poco.drivers.unity3d import UnityPoco

auto_setup(__file__)
poco = UnityPoco()
poco.click([0.25,0.25])

以上只是举例如何通过坐标在两个框架中点击,实际项目中我们还是尽量通过Airtest图片识别和Poco元素定位的方式来点击。

但是我个人觉得‘归一化坐标系’这个名词太生涩了,不能望文知义,所以在以后我的文章中,都统一叫‘屏幕相对坐标’。所以以后看官方文档,提到的‘归一化坐标系’就是我这里的‘屏幕相对坐标’。

什么时候会用到‘屏幕相对坐标’,所有Poco实例API(Poco实例(全局操作) API汇总)、以及部分Poco UI对象 API(Poco UI对象 API汇总),如swipe()

其实‘屏幕绝对坐标’和‘屏幕相对坐标’是可以相互换算的,已知屏幕长宽[100,100],绝对坐标[10,10],那相对坐标就是[10/100,10/100]=[0.1,0.1]
同理,已知屏幕长宽[100,100],相对坐标[0.1,0.1],那绝对坐标就是[100*0.1,100*0.1]=[10,10]

以下为代码中如何获取这些信息:

# -*- encoding=utf8 -*-
__author__ = "测试工程师小站"

from airtest.core.api import *
from poco.drivers.unity3d import UnityPoco

auto_setup(__file__)

poco = UnityPoco()
button = poco(text="测试工程师小站")
# 获取元素的屏幕相对坐标
pos = button.get_position()

picture = Template(r"tpl1635075246242.png", record_pos=(-0.369, -0.796), resolution=(1080, 2340))
# 获取图片的屏幕绝对坐标
postion = wait(picture)

# 获取屏幕分辨率
width, height = device().get_current_resolution()

另外我们也可以通过AirtestIDE来快速获取坐标,详细请看AirtestIDE基本功能(二) 中的选项部分。

局部坐标系(Local Coordinate System)

在讲什么是局部坐标系前,我们要先理解Poco中的一些基本概念。
我们用AirtestIDE定位标题这个元素

在airtest中左右滑动屏幕的代码 airtest点击坐标_在airtest中左右滑动屏幕的代码_02

 

 

如图高亮的长方形,官方叫包围盒,包围盒中心的红点,官方叫anchorPoint,翻译过来就是锚点。

局部坐标系以UI包围盒左上角为原点,向右为x轴,向下为y轴,包围盒宽和高均为单位一。局部坐标系可以更灵活地定位UI内或外的位置,例如(0.5, 0.5)就代表UI的正中央,也就是anchorPoint;超过1或小于0的坐标值则表示UI的外面。

同理,我觉得局部坐标这个名称合理但还差点,以后我的文章中都会以‘元素相对坐标’代替。

大部分Poco UI对象API的操作点或起点都是锚点,即元素相对坐标[0.5,0.5]。锚点是可以改变的,大部分Poco UI对象API都有一个参数focus,可以暂时改变锚点,如我们想点击上图中左下角的五角星

qasite = poco("com.tencent.mm:id/a_g")
qasite.click(focus=[0.1,0.7])

上句只是在点击的时候暂时改变锚点,qasite变量的锚点依然是[0.5,0.5],想永久改变锚点,可以使用focus()方法

qasite = poco("com.tencent.mm:id/a_g").focus([0.1,0.7])
qasite.click()

这样,qaiste的锚点就永远是左下角了

屏幕绝对坐标、屏幕相对坐标、元素相对坐标,理解起来有一定困难,可能今天懂了明天又忘了。没关系,真正到用的时候,多调试几次,把坐标print出来,能达到自己的目的就行。

 

---------------------------------------------------------------------------------