appium2.0+同时实现多点触控和单点触控的多种方法

若未了解单点触控,可先大概了解一下动作构建器Actionbuilder的PointerActions操作
appium2.0+之PointerActions详解

以下放大图片的示例在夜神模拟器上进行。

一、多点触控

1. 多点触控核心实现逻辑

(1)创建一个用于管理用户交互动作的 动作链对象/动作构建对象
(2)多指针创建:通过add_pointer_input创建多个 touch 类型的虚拟手指
(3) 定义多个虚拟手指的同步动作序列
(4)统一执行perform,实现多点触控

2. 执行时间逻辑

动作按 “时间轴” 执行,而非代码顺序,在同一个ActionBuilderActionChains中,两个手指(finger1finger2)是否会 “同时运行”,不取决于代码的编写顺序,而取决于动作的 “时间线设置”—— 即通过duration(持续时间)和pause(暂停时间)定义的动作时序。同一时间点的动作会 “并行执行”,不同时间点的动作会 “串行执行”。

二、单点触控+多点触控案例

代码执行前准备

  • 命令行启动appium服务(版本2.19.0):
appium --address 127.0.0.1 --log-level debug --use-drivers uiautomator2
  • 模拟器打开,命令行adb devices显示设备已连接
    在这里插入图片描述

1. 方法1:建立两个Actionbuilder对象

逻辑:建立两个Actionbuilder对象,一个用来单点触控,一个用来多点触控

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : class04_multiTouch.py
@Time    : 2025/7/29 14:22
@desc   : 多点触控示例,放大图片
多点触控核心实现:
通过创建两个PointerInput对象模拟两个手指(finger1和finger2)
actionbuilder通过add_pointer_input添加多个触控设备
手指添加操作,最后perform,实现多点触控
'''
from time import sleep
from appium import webdriver
from appium.options.android import UiAutomator2Options  # 导入 Android 选项类
from selenium.webdriver.common.actions.action_builder import ActionBuilder

# 手机/模拟器,配置信息
desired_caps = {
    "platformName": "Android",
    "platformVersion": "7.1.2",
    "deviceName": "127.0.0.1:62001",
    "appPackage": "com.android.gallery3d",
    # 获取包名、界面名:adb shell dumpsys window|findstr mCurrentFocus
    "appActivity": "com.android.gallery3d.app.GalleryActivity",
    "noReset": False
}

# 显式传入 options 参数(适用于必须使用高版本 Selenium 的场景)
# 将 desired_caps 转换为 Options 实例
options = UiAutomator2Options().load_capabilities(desired_caps)

# 传入 options 参数
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4723',
    options=options  # 必须传入 options,替代原来的 desired_capabilities
)

# 获取窗口尺寸
window_size = driver.get_window_size() #返回dict格式的当前窗口屏幕尺寸
width = window_size['width']  # 获取宽度
height = window_size['height']  # 获取高度
# 第一根手指的移动位置
startX1 = width*0.6
startY1 = height*0.4
endX1 = width*0.9
endY1 = height*0.1
# 第二根手指移动位置
startX2 = width*0.4
startY2 = height*0.6
endX2 = width*0.1
endY2 = height*0.9

# 分为两个builder(推荐两个builder统一使用touch类型),第一个用来先执行单击操作后perform,第二个builder做多点触控两个手指同时操作
# 创建单点触控的builder
singleBuilder = ActionBuilder(driver)
singleAct = singleBuilder.add_pointer_input('touch', 'singleAct')

# 创建双指多点触控的Builder
zoomBuilder = ActionBuilder(driver)
finger1 = zoomBuilder.add_pointer_input('touch', 'finger1')
finger2 = zoomBuilder.add_pointer_input('touch', 'finger2')

sleep(3) #待页面稳定
# 单击选择中间的图片
singleAct.create_pointer_move(duration=0, x=width*0.5, y=height*0.5)
singleAct.create_pointer_down() #按下
singleAct.create_pause(0.1) #间隔
singleAct.create_pointer_up(0) #抬起左键,0左键,1滚轮,2右键
singleAct.create_pause(1) #间隔1s
singleBuilder.perform()

# 多点触控操作
# 手指1操作
finger1.create_pointer_move(duration=0, x=startX1, y=startY1) # 手指1移动到起点
finger1.create_pointer_down()
finger1.create_pause(0.2) #按下后短暂停留,单位s
finger1.create_pointer_move(500, endX1, endY1)
finger1.create_pointer_up(0) #抬起

# 手指2操作
# 注意,finger2的开始执行时间不取决于代码的编写顺序,而取决于动作的 “时间线设置”,
# duration=0即在时间轴上0开始执行,因为finger1的时间轴开始也是0,这样就实现两根手指同时开始动作,若finger2的duration=1000,那就是在时间轴1s是才开始finger2的执行
finger2.create_pointer_move(duration=0, x=startX2, y=startY2) # 手指2移动到起点,duration单位为ms
finger2.create_pointer_down()
finger2.create_pause(0.2) #按下后短暂停留,单位s
finger2.create_pointer_move(500, endX2, endY2)
finger2.create_pointer_up(button=0) #抬起 button=0为抬起左键,1为滚轮,2为右键


# 执行完整动作链
zoomBuilder.perform()
sleep(2)
driver.quit()

2. 方法2:单点触控通过Actionchains,多点触控通过Actionbuilder实现

用下面的代码替换掉方法1里单点触控的代码即可:

# 创建单点触控的动作链
singleChains = ActionChains(driver)
# 通过Actionchains单击选择中间的图片
imgEl = driver.find_element('id', 'android:id/content')
singleChains.click(imgEl)
singleChains.pause(1) #暂停1s
singleChains.perform()

完整代码

'''
@Author  : 草木零
@Software: PyCharm
@File    : class05_actionChains.py
@Time    : 2025/7/30 11:39
@desc   : 先通过Actionchains实现单点触控,再通过Actionbuilder实现多点触控
'''
from time import sleep
from appium import webdriver
from appium.options.android import UiAutomator2Options  # 导入 Android 选项类
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver import ActionChains
# 手机/模拟器,配置信息
desired_caps = {
    "platformName": "Android",
    "platformVersion": "7.1.2",
    "deviceName": "127.0.0.1:62001",
    "appPackage": "com.android.gallery3d",
    # 获取包名、界面名:adb shell dumpsys window|findstr mCurrentFocus
    "appActivity": "com.android.gallery3d.app.GalleryActivity",
    "noReset": False
}

# 显式传入 options 参数(适用于必须使用高版本 Selenium 的场景)
# 将 desired_caps 转换为 Options 实例
options = UiAutomator2Options().load_capabilities(desired_caps)

# 传入 options 参数
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4723',
    options=options  # 必须传入 options,替代原来的 desired_capabilities
)

# 获取窗口尺寸
window_size = driver.get_window_size() #返回dict格式的当前窗口屏幕尺寸
width = window_size['width']  # 获取宽度
height = window_size['height']  # 获取高度
# 第一根手指的移动位置
startX1 = width*0.6
startY1 = height*0.4
endX1 = width*0.9
endY1 = height*0.1
# 第二根手指移动位置
startX2 = width*0.4
startY2 = height*0.6
endX2 = width*0.1
endY2 = height*0.9

# 创建单点触控的动作链
singleChains = ActionChains(driver)

# 创建双指多点触控的Builder
zoomBuilder = ActionBuilder(driver)
finger1 = zoomBuilder.add_pointer_input('touch', 'finger1')
finger2 = zoomBuilder.add_pointer_input('touch', 'finger2')

sleep(3) #待页面稳定
# 通过Actionchains单击选择中间的图片
imgEl = driver.find_element('id', 'android:id/content')
singleChains.click(imgEl)
singleChains.pause(1) #暂停1s
# 执行动作链
singleChains.perform()

# 多点触控操作
# 手指1操作
finger1.create_pointer_move(duration=0, x=startX1, y=startY1) # 手指1移动到起点
finger1.create_pointer_down()
finger1.create_pause(0.2) #按下后短暂停留,单位s
finger1.create_pointer_move(500, endX1, endY1)
finger1.create_pointer_up(0) #抬起

# 手指2操作
# 注意,finger2的开始执行时间不取决于代码的编写顺序,而取决于动作的 “时间线设置”,
# duration=0即在时间轴上0开始执行,因为finger1的时间轴开始也是0,这样就实现两根手指同时开始动作,若finger2的duration=1000,那就是在时间轴1s是才开始finger2的执行
finger2.create_pointer_move(duration=0, x=startX2, y=startY2) # 手指2移动到起点,duration单位为ms
finger2.create_pointer_down()
finger2.create_pause(0.2) #按下后短暂停留,单位s
finger2.create_pointer_move(500, endX2, endY2)
finger2.create_pointer_up(button=0) #抬起 button=0为抬起左键,1为滚轮,2为右键

# 执行完整动作链
zoomBuilder.perform()
sleep(2)
driver.quit()

3. 方法3:创建两个动作链Actionchains对象

用下面的代码替换方法2中关于多点触控的代码即可:

# 创建双指多点触控的Actionchains实例
zoomChains = ActionChains(driver)
finger1 = zoomChains.w3c_actions.add_pointer_input('touch', 'finger1')
finger2 = zoomChains.w3c_actions.add_pointer_input('touch', 'finger2')
# ......省略的中间代码,其实这里finger1/2可调用的方法同Actionbuilder创建的手指是一样的(点开两者的add_pointer_input查看底层代码就知道是一样的返回),所以其他地方不用改

# 执行完整动作链
zoomChains.perform()

完整代码

#!/usr/bin/env python
# encoding: utf-8
'''
@Author  : 草木零
@Software: PyCharm
@File    : class05_actionChains02.py
@Time    : 2025/7/30 12:03
@desc   : 通过Actionchains实现多点触控,放大图片
操作:建立一个Actionchains实例来管理单点触控的操作,再建立另一个Actionchains实例来管理多点触控的操作
'''
from time import sleep
from appium import webdriver
from appium.options.android import UiAutomator2Options  # 导入 Android 选项类
from selenium.webdriver import ActionChains


# 手机/模拟器,配置信息
desired_caps = {
    "platformName": "Android",
    "platformVersion": "7.1.2",
    "deviceName": "127.0.0.1:62001",
    "appPackage": "com.android.gallery3d",
    # 获取包名、界面名:adb shell dumpsys window|findstr mCurrentFocus
    "appActivity": "com.android.gallery3d.app.GalleryActivity",
    "noReset": False
}

# 显式传入 options 参数(适用于必须使用高版本 Selenium 的场景)
# 将 desired_caps 转换为 Options 实例
options = UiAutomator2Options().load_capabilities(desired_caps)

# 传入 options 参数
driver = webdriver.Remote(
    command_executor='http://127.0.0.1:4723',
    options=options  # 必须传入 options,替代原来的 desired_capabilities
)

# 获取窗口尺寸
window_size = driver.get_window_size() #返回dict格式的当前窗口屏幕尺寸
width = window_size['width']  # 获取宽度
height = window_size['height']  # 获取高度
# 第一根手指的移动位置
startX1 = width*0.6
startY1 = height*0.4
endX1 = width*0.9
endY1 = height*0.1
# 第二根手指移动位置
startX2 = width*0.4
startY2 = height*0.6
endX2 = width*0.1
endY2 = height*0.9

# 创建单点触控的动作链
singleChains = ActionChains(driver)

# 创建双指多点触控的Actionchains实例
zoomChains = ActionChains(driver)
finger1 = zoomChains.w3c_actions.add_pointer_input('touch', 'finger1')
finger2 = zoomChains.w3c_actions.add_pointer_input('touch', 'finger2')

sleep(3) #待页面稳定
# 通过Actionchains单击选择中间的图片
imgEl = driver.find_element('id', 'android:id/content')
singleChains.click(imgEl)
singleChains.pause(1) #暂停1s
# 执行动作链
singleChains.perform()

# 多点触控操作
# 手指1操作
finger1.create_pointer_move(duration=0, x=startX1, y=startY1) # 手指1移动到起点
finger1.create_pointer_down()
finger1.create_pause(0.2) #按下后短暂停留,单位s
finger1.create_pointer_move(500, endX1, endY1)
finger1.create_pointer_up(0) #抬起

# 手指2操作
# 注意,finger2的开始执行时间不取决于代码的编写顺序,而取决于动作的 “时间线设置”,
# duration=0即在时间轴上0开始执行,因为finger1的时间轴开始也是0,这样就实现两根手指同时开始动作,若finger2的duration=1000,那就是在时间轴1s是才开始finger2的执行
finger2.create_pointer_move(duration=0, x=startX2, y=startY2) # 手指2移动到起点,duration单位为ms
finger2.create_pointer_down()
finger2.create_pause(0.2) #按下后短暂停留,单位s
finger2.create_pointer_move(500, endX2, endY2)
finger2.create_pointer_up(button=0) #抬起 button=0为抬起左键,1为滚轮,2为右键

# 执行完整动作链
zoomChains.perform()
sleep(2)
driver.quit()

三、扩展:ActionChains部分底层代码

from selenium.webdriver import ActionChains

pycharm中按住Ctrl+左键点击from selenium.webdriver import ActionChains中的ActionChains,可查看ActionChains的实现代码,发现它还是使用的 ActionBuilder 类来实现,如下图:
在这里插入图片描述

Actionchains封装的方法

在这里插入图片描述

如果Actionchains中已实现的封装方法不够用,我们再通过w3c_actionspointer_action里的方法来实现,前面已细讲PointerActions类。
appium2.0+之PointerActions详解
下面展示如何从ActionChains是如何从高到低看到PointerAction的。

ActionChains(driver).w3c_actions中的一些方法

图片:
在这里插入图片描述

其中ActionChains(driver).w3c_actions.add_pointer_input()里的类型kind有三种:mouse(鼠标),touch(触屏),pen(笔触)
在这里插入图片描述

w3c_actions.pointer_action中实现的方法

所以一层层走下来,如果Actionchains类中已封装实现的方法不够满足我们的需求,是可以通过更底层的ActionChains(driver).w3c_actions.pointer_action的方法来实现所求的,而PointerActions类前面已具体讲解使用方法
appium2.0+之PointerActions详解
在这里插入图片描述

资源下载链接为: https://pan.quark.cn/s/9648a1f24758 FASTA格式是生物信息学中一种重要的文本格式,用于表示核酸氨基酸序列。在该格式中,DNA的四种碱基(腺嘌呤、胸腺嘧啶、胞嘧啶鸟嘌呤)分别用A、T、C、G表示,而RNA中胸腺嘧啶被尿嘧啶(U)替代。蛋白质序列则用20个单字母代码表示氨基酸,如苯丙氨酸用F表示,酪氨酸用Y表示。许多生物信息学数据库,如DIPNCBI,都以FASTA格式存储大量生物序列数据供研究者使用。研究者在使用BLAST等序列比对工具后,比对结果也常以FASTA格式呈现。在分析这些序列时,研究者可能需要对特定功能域或功能位点进行研究,例如在蛋白质相互作用预测中,对氨基酸序列进行二联体(连续两个氨基酸)或三联体(连续三个氨基酸)特征编码分析,这有助于了解蛋白质的结构功能。 为了满足对大型FASTA格式序列文件进行特定长度词条特征分析的需求,本文提出了一种新的算法——压缩索引树统计算法。压缩索引树是一种高效存储检索序列数据的数据结构,该算法通过减少存储空间需求加快查询速度,优化了现有的生物信息学分析工具,这些工具大多缺乏特定长度词条特征分析功能。在FASTA格式文件中,序列的统计是对28个字母的字符串进行的。文件中,序列说明行以“>”开头,后面是描述序列的文字,之后直到下一个“>”开头的说明行之间是序列本身。目前,常见的分析工具如matlab生物信息学工具箱、PexFinderBLAST等,均未提供特定长度词条特征分析功能。 文章提到的作者初砚硕是生物信息学领域的学者,他在东北林业大学获得计算机应用技术硕士学位,还在大连理工大学分别获得生物工程计算机应用技术(第二学位)学士学位。通信联系人刘亚秋也具备丰富的研究背景。FASTA格式作为生物信息学研究的基础,简洁地存储了大量核酸蛋白质序列信息。随着生物信息学
内容概要:本文档《MATLAB 语言从入门到精通:基础语法与实战案例教程》系统介绍了MATLAB的基础知识及其应用。首先概述了MATLAB的定义、核心优势适用场景,接着详细讲述了MATLAB的安装与界面构成。文档深入浅出地讲解了MATLAB的基础语法,包括变量与数据类型、运算符、流程控制语句、函数定义与调用等。随后,重点介绍了MATLAB的核心数据结构——矩阵与数组的操作,涵盖矩阵创建、向量操作、单元格数组结构体的使用。绘图与可视化部分展示了如何使用`plot`、`subplot`、`plot3`等函数进行二维三维图形的绘制。数值计算章节涵盖了线性代数求解、曲线拟合、数值积分微分方程求解等内容。符号计算部分介绍了符号变量、微积分运算方程求解。最后,通过一个信号处理与频谱分析的实战案例,演示了MATLAB在实际问题中的应用,并分享了一些高效的编程技巧。; 适合人群:具备一定数学基础的工科学生、科研人员以及对数据分析、算法开发感兴趣的初学者。; 使用场景及目标:①学习MATLAB的基本语法核心数据结构,掌握矩阵、向量、单元格数组结构体的操作;②理解并能够应用MATLAB的绘图可视化功能;③掌握线性代数求解、曲线拟合、数值积分微分方程求解等数值计算方法;④学会使用符号计算工具进行精确的数学表达式处理;⑤通过实战案例,掌握信号处理与频谱分析的应用技能。; 其他说明:文档提供了丰富的实例代码片段,帮助读者更好地理解掌握MATLAB的各项功能。推荐结合官方文档、经典教材在线课程进行学习,通过大量实践提升应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值