【测试】pywinauto的简单使用(安装、常用对象、元素控件、鼠标操作、键盘操作)

1.说明

pywinauto是一个用于自动化Python 模块,适合Windows系统的软件(GUI),可以通过Pywinauto遍历窗口(对话框)和窗口里的控件,也可以控制鼠标和键盘输入,所以它能做的事情比之前介绍的pysimplegui更多

2.安装

一般使用pip安装就行了

pip install pywinauto

官网文档:https://pywinauto.readthedocs.io/en/latest/

3.Application

我们要控制软件的第一件事就是启动一个Windows软件,每一个软件(进程)都是一个Application对象

实例化Application对象的时候可以传入一个backend参数,可选值为win32(默认)和 uia

win32对应的框架:MFC、VB6、VCL、简单的 WinForms 控件和大多数旧的遗留应用程序
uia对应的框架:WinForms、WPF、商店应用程序、Qt5、浏览器
如果无法知道要测试的软件是属于哪种框架,可以使用 Inspect(对应uia)Spy++(对应win32) 看看,你看哪个显示得更全就选哪个。Inspect和Spy++需要自己安装一下

下面是Application对象的主要方法

方法常用参数说明
start()cmd_line、timeout、retry_interval通过cmd命令启动一个软件(进程)
connect()process、handle、path、timeout连接一个进程,一般是使用进程号(任务管理器可以看到)
top_window()/获取应用的顶层窗口
window()title、title_re、class_name、best_match获取单个窗口(WindowSpecification)
windows()title、title_re、class_name获取多个窗口(UIAWrapper)
is64bit()/是否64位应用
cpu_usageintervalCPU占用率
wait_cpu_usage_lower()threshold、timeout等待CPU占率小于某个阈值
active()()/搜索返回一个激活的窗口
kill()soft结束进程
wait_for_process_exit()timeout、retry_interval等待进程结束

举例,启动一个微信应用,通过进程号连接,进程号就是在任务管理器里详细信息看到的PID
在任务管理器查看进程号

from pywinauto import Application

app = Application(backend="uia")
# app.start(r"D:\Program Files (x86)\Tencent\WeChat\WeChat.exe")
app.connect(process=6556)
print("is64bit:", app.is64bit())
print("cpu_usage:", app.cpu_usage())
app.wait_cpu_usage_lower()
# app.active()  # 如果指定时间内不激活则报错
print("kill:", app.kill())
print("wait_for_process_exit:", app.wait_for_process_exit())

4.WindowSpecification

我们要获取窗口,一个窗口都是一个WindowSpecification对象,可以通过Application对象的window()方法获取,参数可以是title、classname或者best_match等,这都可以在inspect.exe上看到,不过需要注意的是inspect看到的Name其实对应的是window()的title参数
在这里插入图片描述

WindowSpecification对象常用的方法如下

方法常用参数说明
maximize()/最大化窗口
minimize()/最小化窗口
restore()/恢复窗口
close()/关闭窗口
get_show_state()/获取窗口状态,0正常1最大化2最小化
was_maximized()/当前是否最大化
draw_outline()colour、thickness给窗口画个框以便定位
print_control_identifiers()/打印所有子窗口和子元素(会打印出对应的control_type)
child_window()title、control_type获取子窗口
exists()timeout窗口是否存在
wait()wait_for, timeout等待窗口变成某个状态(exists、visible、enabled、ready、active)
wait_not()wait_for_not, timeout等待窗口不处于某个状态(exists、visible、enabled、ready、active)

举个栗子

dlg = app.window(class_name="WeChatMainWndForPC")
# dlg = app.window(title="微信")
print("get_show_state:", dlg.get_show_state())
print("was_maximized:", dlg.was_maximized())
dlg.print_control_identifiers()
dlg.draw_outline()
dlg.maximize()
dlg.restore()
dlg.minimize()
dlg.close()

5.元素控件

一个窗口里一般都会有各种各样的元素,比如说按钮 (Button)、编辑栏(Edit)、树状视图(Tree View)、复选框(CheckBox)、对话框(Dialog)、工具栏(Toolbar)、状态栏(StatusBar)、列表框(ListBox)、窗格(Pane)、菜单(Menu)、菜单栏(MenuItem)、静态内容(Static)、工具提示(ToolTips)、列表控件(ListView)、单选框(RadioButton)、组合框(ComboBox)、选项卡控件(TabControl)、组框 (GroupBox)、弹出菜单(PopupMenu)、头部(Header)等

因为控件类型太多了不能一个一个学习,但是它们都有一个 element_info 的属性,访问之后会返回一个继承于ElementInfo的对象(UIAElementInfo或HwndElementInfo),比较重要的属性或方法如下

方法或属性常用参数说明
name/元素的真实名(一般是title)
visible/元素是否可见
rich_text/元素的全名
rectangle/返回元素的位置以及宽高
class_name/类名
enabled/元素是否处于可用状态
parent/返回父元素
children()title、title_re、class_name、best_match返回符合要求的子元素(列表)
iter_children()title、title_re、class_name、best_match迭代符合要求的子元素(生成器)

这些元素除了有element_info可以获取一些元素的主要信息,它们还都被包装成一个Wrapper,所以也可以学一下BaseWrapper的常用方法和属性。其实BaseWrapper的方法基本上都是对ElementInfo进一步包装,我只列出部分方法,如下表

方法或属性常用参数说明
element_info/返回当前元素的ElementInfo对象
from_point()x、y通过坐标查找ElementInfo
class_name()/类名,实际是调用element_info.class_name
friendly_class_name()/友好的类名,同上
window_text()/元素的文本,实际是调用element_info.rich_text
is_visible()/元素是否可见,实际是调用element_info.visible
is_enabled()/元素是否可用,实际是调用element_info.enabled
rectangle()/元素的位置和宽高,实际是调用element_info.rectangle
process_id()/进程号,实际是调用element_info.process_id
draw_outline()colour、thickness给当前元素画个框
click_input()button、coords、double鼠标操作,实际是调用mouse模块的_perform_click_input()
type_keys()/键盘操作,实际是调用keyboard模块的send_keys()
dlg = app.window(class_name="WeChatMainWndForPC")
list_data = dlg.child_window(title="会话", control_type="List")
for item in list_data:
    print(type(item))
    element_info = item.element_info
    print(type(element_info))
    print("window_text:", )
    print("rich_text:", element_info.rich_text)
    print("name:", element_info.name)
    print("visible:", element_info.visible)
    print("rectangle:", element_info.rectangle)
    print("class_name:", element_info.class_name)
    print("enabled:", element_info.enabled)
    print("parent:", element_info.parent)
    print("children:", element_info.children())
    print("iter_children:", element_info.iter_children())
    if item.window_text() == "文件传输助手":
        item.click_input()
        item.type_keys("冰冷的希望")
        item.type_keys("{VK_RETURN}")
    print()

说明一下,每个控件元素都有对应的Wrapper,所以上面的方法也不一定都用,需要根据实际情况进行测试区分。另外,比较有用的click_input()type_keys()这两个方法分别用于操作鼠标和键盘(输入),下面我会单独拿出来说一下

6.鼠标操作

鼠标点击肯定离不开点击的位置,桌面就是一个坐标,左上角为坐标原点,往右是X轴正向,往下是Y轴正向。pywinauto提供了一个mouse模块用于鼠标操作,最核心的方法是_perform_click_input(),不过它是一个私有方法,我们调用的是基于它的封装方法,如下表

方法参数
click()button、coords单击鼠标某个键
double_click()button、coords双击鼠标某个键
right_click()coords单击鼠标右键
move()coords移动鼠标
press()button、coords按下鼠标
release()button、coords放开鼠标
scroll()coords、wheel_dist滚动鼠标滚轮
wheel_click()coords单击鼠标滚轮

参数说明:
参数button的默认值都是“left”,即鼠标左键,可选值有left、right、middle、move、wheel、x
参数coords 的默认值都是元组(0, 0),元组里的两个整数分别是X、Y轴的值
参数wheel_dist表示滚动的距离,大于0是向上滚动,小于0是向下滑动

举个栗子

from pywinauto import Application, mouse

app = Application(backend="uia")
app.connect(process=4352)
dlg = app.window(class_name="WeChatMainWndForPC")
list_data = dlg.child_window(title="会话", control_type="List")
for item in list_data:
    if item.window_text() == "文件传输助手":
        # item.click_input()
        rectangle = item.element_info.rectangle
        x = int((rectangle.left + rectangle.right) / 2)
        y = int((rectangle.top + rectangle.bottom) / 2)
        mouse.click(button='left', coords=(x, y))
        time.sleep(1)
        mouse.click("right", (x, y))
        time.sleep(1)
        mouse.move((x - 50, y))  # 往左边移动50个像素
        time.sleep(1)
        mouse.click(coords=(x, y))
        break

7.键盘操作

键盘操作主要是按下键盘上的按键,相关方法在keyboard模块,最最主要的是send_keys()方法,第一个参数keys就是我们需要按下的按键,其他参数比如说with_spaces、with_tabs、with_newlines、turn_off_numlock、set_foreground、vk_packet,一看就知道作用,而且都是布尔值,此处不进行举例

pywinauto支持的完整的按键可以在官方文档查看,https://pywinauto.readthedocs.io/en/latest/code/pywinauto.keyboard.html
下面我列举出的是一些比较常用的按键

按键符号说明
ShiftVK_SHIFT上档键
CtrlVK_CONTROL、VK_LCONTROL、VK_RCONTROLCtrl键、左右Ctrl键
AltVK_MENUAlt键
WindowsVK_LWIN、VK_RWIN左右win键
SpaceVK_SPACE空格键
backspaceBACKSPACE退格键
enterENTER回车键
escESC退出键
tableVK_TAB制表键
left、right、up、downVK_LEFT、VK_RIGHT、VK_UP、VK_DOWN上下左右方向键
f1~f24VK_F1、VK_F2…VK_F24f1到f24
capslockCAPSLOCK大写键

说明:
1.使用按键时需要搭配大括号,比如说按下回车键是 '{ENTER}' (是字符串)
2.在Windows平台默认是发送虚拟按键的,以VK_开头的按键,都是指虚拟按钮,如果不想使用虚拟按钮可以把VK_前缀去掉,把send_keys()的vk_packet参数改为False即可

单个按键按下抬起还不够,往往需要组合键,这时候就需要修饰符了,在大括号里可以使用downup控制按键什么时候按下和抬起,如果后面加上数字,表示按下多少次

list_data = dlg.child_window(title="会话", control_type="List")
for item in list_data:
    if item.window_text() == "文件传输助手":
        item.click_input()
        # item.type_keys("冰冷的希望")
        send_keys("   ")  # 随便输入字符串
        send_keys("{VK_CONTROL down} a {VK_CONTROL up}")  # 快捷键Ctrl+a(先按下Ctrl,再按下a,最后放开Ctrl)
        send_keys("{BACKSPACE}")  # 按下退格键删除文本
        send_keys("{. 6}")  # 按6次小数点
        send_keys("冰冷的希望{ENTER}")  # 输入文本,按下回车键

当然,很多时候使用downup修饰感觉不够简洁,所以pywinauto还提供了简化写法,使用+代替{VK_SHIFT},使用^代替{VK_CONTROL},使用%代替{VK_MENU}

send_keys('^a^c') # 按下Ctrl+a之后再按下Ctrl+c,即全选复制
send_keys('+{INS}') # 按下Shift+Ins键
send_keys('%{F4}') # 按下Alt+F4键

如果不想按下按钮,纯属想要输入纯字符串,那就需要取消转义了,注意修饰符和按钮的写法是不一样的

send_keys('{^}a{^}c{%}') # 输入字符串"^a^c%"而不是当成快捷键
send_keys('{{}ENTER{}}') # 输入字符串"{ENTER}"而不是按下回车键

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/87083.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

36k字从Attention解读Transformer及其在Vision中的应用(pytorch版)

文章目录 0.卷积操作1.注意力1.1 注意力概述(Attention)1.1.1 Encoder-Decoder1.1.2 查询、键和值1.1.3 注意力汇聚: Nadaraya-Watson 核回归1.2 注意力评分函数1.2.1 加性注意力1.2.2 缩放点积注意力1.3 自注意力(Self-Attention)1.3.1 自注意力的定义和计算1.3.2 自注意…

数据结构初阶--排序

目录 一.排序的基本概念 1.1.什么是排序 1.2.排序算法的评价指标 1.3.排序的分类 二.插入排序 2.1.直接插入排序 2.2.希尔排序 三.选择排序 3.1.直接选择排序 3.2.堆排序 重建堆 建堆 排序 四.交换排序 4.1.冒泡排序 4.2.快速排序 快速排序的递归实现 法一&a…

『SEQ日志』在 .NET中快速集成轻量级的分布式日志平台

📣读完这篇文章里你能收获到 如何在Docker中部署 SEQ:介绍了如何创建和运行 SEQ 容器,给出了详细的执行操作如何使用 NLog 接入 .NET Core 应用程序的日志:详细介绍了 NLog 和 NLog.Seq 来配置和记录日志的步骤日志记录示例&…

CSS background 背景

background属性为元素添加背景效果。 它是以下属性的简写,按顺序为: background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 以下所有示例中的花花.jpg图片的大小是4848。 1 background-color background-col…

【rust/egui】(四)看看template的app.rs:update以及组件TopBottomPanelButton

说在前面 rust新手,egui没啥找到啥教程,这里自己记录下学习过程环境:windows11 22H2rust版本:rustc 1.71.1egui版本:0.22.0eframe版本:0.22.0上一篇:这里 update update实际上还是eframe::App的…

BaiqiSoft MstHtmlEditor for .NET Crack

BaiqiSoft MstHtmlEditor for .NET Crack BaiqiSoft MstHtmlEditor获取.NET for win表单被认为是一个可以被用户轻松灵活地集成到C#、VB.NET甚至WPF软件中的元素。负责编辑的控制器,用于.NET Win Forms的MstHtmlEditor,允许用户和开发人员,甚…

stm32之11.USART串口通信

可以添加上拉电阻&#xff0c;但会增加功耗&#xff0c;传输距离变长 要添加库函数USART 官方参考文档说明书位置 ALT&#xff0b;左键可实现整体删除&#xff08;如下图&#xff09; 输出模式第三种模式AF ---------------------- 源码 远程控制pc端 #include <stm32f4x…

UE4/5Niagara粒子特效之Niagara_Particles官方案例:2.4->3.2

之前的案例 UE4/5Niagara粒子特效之Niagara_Particles官方案例&#xff1a;1.1-&#xff1e;1.4_多方通行8的博客-CSDN博客 UE4/5Niagara粒子特效之Niagara_Particles官方案例&#xff1a;1.5-&#xff1e;2.3_多方通行8的博客-CSDN博客 2.4 Location Events 这次的项目和之…

江西抚州新能源汽车3d扫描零部件逆向抄数测量改装-CASAIM中科广电

汽车改装除了在外观方面越来越受到消费者的青睐&#xff0c;在性能和实用性提升上面的需求也是日趋增多&#xff0c;能快速有效地对客户指定汽车零部件进行一个改装&#xff0c;是每一个汽车改装企业和工程师的追求&#xff0c;也是未来消费者个性化差异化的要求。下面CASAIM中…

【Docker】存储卷Volume

Docker Volume概念 什么是存储卷 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着&#xff0c;当我们在容器中的这个目录下写入数据时&#xff0c;容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的…

裂缝检测,只依赖OPENCV,基于YOLO8S

裂缝检测&#xff0c;只依赖OPENCV&#xff0c;YOLOV8S 现在YOLOV8S训练目标非常方便&#xff0c;可以直接转换成ONNX让OPENCV调用&#xff0c;支持C/PYTHON&#xff0c;原理很简单&#xff0c;自己找博客&#xff0c;有兴趣相互交流

数字化技术无限延伸,VR全景点亮智慧生活

随着互联网的发展&#xff0c;我们无时无刻不再享受着互联网给我们带来的便利&#xff0c;数字化生活正在无限延伸&#xff0c;各行各业也开始积极布局智能生活。要说智慧生活哪个方面应用的比较多&#xff0c;那应该就是VR全景了&#xff0c;目前VR全景已经被各个行业广泛应用…

Mesa 23.2 开源图形栈现已可供下载

作为 Mesa 23 系列的第二个重要版本&#xff0c;Mesa 23.2 开源图形栈现已可供下载&#xff0c;它为 AMD GPU 的 RADV Vulkan 驱动程序带来了新功能&#xff0c;改进了 Linux 游戏&#xff0c;并新增了 Asahi 功能。 Mesa 23.2 的亮点包括 Asahi 上的 OpenGL 3.1 和 OpenGL ES …

前端需要理解的HTML知识

HTML&#xff08;超文本标记语言&#xff0c;HyperText Markup Language&#xff09;不是编程语言&#xff0c;而是定义了网页内容的含义和结构的标记语言。。“超文本”&#xff08;hypertext&#xff09;是指连接单个网站内或多个网站间的网页的链接。HTML 使用“标记”&…

怎么检测UI卡顿?(线上及线下)

什么是UI卡顿&#xff1f; 在Android系统中&#xff0c;我们知道UI线程负责我们所有视图的布局&#xff0c;渲染工作&#xff0c;UI在更新期间&#xff0c;如果UI线程的执行时间超过16ms&#xff0c;则会产生丢帧的现象&#xff0c;而大量的丢帧就会造成卡顿&#xff0c;影响用…

无限计算力:探索云计算的无限可能性

这里写目录标题 前言云计算介绍服务模型&#xff1a; 应用领域&#xff1a;云计算主要体现在生活中的地方云计算未来发展的方向 前言 云计算是一种基于互联网的计算模型&#xff0c;通过它可以实现资源的共享、存储、管理和处理。它已经成为许多个人、企业和组织的重要技术基础…

lvs实现DR模型搭建

一&#xff0c;实现DR模型搭建 1&#xff0c; 负载调度器配置 1.1调整ARP参数 vim /etc/sysctl.conf net.ipv4.conf.all.send_redirects 0 net.ipv4.conf.default.send_redirects0 net.ipv4.conf.ens33.send_redirects 0 sysctl -p 1.2 配置虚拟IP地…

UE4/5Niagara粒子特效之Niagara_Particles官方案例:1.1->1.4

目录 1.1-Simple Sprite Emitter ​编辑 发射器更新 粒子生成 粒子更新 1.2-Simple Sprite Emitter 发射器更新 粒子生成 粒子更新 渲染 1.3-Simple GPU Emitter 属性 发射器更新 粒子生成 粒子更新 1.4-Sprite Facing 发射器更新 粒子生成 粒子更新 通过对官方…

opencv进阶19-基于opencv 决策树cv::ml::DTrees 实现demo示例

opencv 中创建决策树 cv::ml::DTrees类表示单个决策树或决策树集合&#xff0c;它是RTrees和 Boost的基类。 CART是二叉树&#xff0c;可用于分类或回归。对于分类&#xff0c;每个叶子节点都 标有类标签&#xff0c;多个叶子节点可能具有相同的标签。对于回归&#xff0c;每…

高品质的运动耳机有哪些、高端运动耳机推荐

随着健康生活理念的广泛普及&#xff0c;对于很多人来说&#xff0c;运动已经成为他们日常生活不可或缺的重要组成部分。在激情四溢的健身运动中&#xff0c;我们既能够放松身心&#xff0c;减轻工作压力&#xff0c;又能够强健身体&#xff0c;增强免疫力&#xff0c;可谓一举…