GUI 自动化测试详解(一):从工具选型到 pywinauto 核心操作全指南
一、GUI 自动化:为什么要做?
1. 核心意义:解决 “重复、低效、易出错” 的测试痛点
- 提升测试效率:手动测试重复用例(比如反复验证软件基础功能)时,测试人员要重复操作、耗时且易出错;GUI 自动化工具能 “按预设逻辑批量执行”,短时间完成大量重复工作。
- 降低人力成本:原本多名测试人员花数小时 / 天数的工作,写好自动化脚本后,工具能自动完成,把测试人员从繁琐重复中解放出来。
2. 适用场景:“重复、稳定、批量” 的 GUI 测试场景
GUI 自动化适合需要重复执行、要求操作一致性的场景,核心作用是 “保障软件质量 + 提效”:
- 覆盖软件开发全阶段:从集成测试到验收测试,能验证 “界面元素显示、交互流畅度、功能是否符合预期”。
- 支持特殊测试需求:模拟不同用户环境测兼容性 / 稳定性;大规模测试时能快速反馈,支撑持续集成 / 交付、加速开发周期。
⚠️ 注意:依赖界面元素稳定性—— 如果 UI 频繁变动、交互复杂,自动化脚本的维护成本会很高。


二、为什么选 pywinauto?
pywinauto 是基于 Python 的 Windows 桌面 GUI 自动化库,核心是 “模拟用户操作(点击、输入),精准控制 Windows 窗口 / 控件”,适合自动化测试、批量任务、办公流程优化。
1. 底层技术:适配不同 Windows 应用框架
它靠两种 “后端模式” 覆盖不同类型的 Windows 应用:
win32模式:适配传统框架(比如 MFC、VB6 开发的旧应用)。uia模式:适配现代框架(比如 WinForms、WPF、QT5,以及部分浏览器)。
2. 优势:专门为 Windows 场景设计的 “易用 + 强适配”
- Python 生态友好:Python 简洁易学,脚本开发 / 维护成本低。
- Windows 兼容性好:支持 Win7 及以上版本,能对接原生控件(按钮、文本框)和第三方控件(WPF、QT)。
- 降低开发成本:自带 “动态等待控件加载” 机制(不用手动写等待代码);有
pywinauto.findwindows模块辅助定位控件,调试方便。 - 社区支撑强:开源项目,持续更新,文档 / 示例丰富。
3. 局限性:只聚焦 Windows,对部分场景 “不适用”
- 平台限制:仅支持 Windows,不能用于 Mac/Linux。
- 控件适配有限:非标准自定义控件(比如某些自研控件)可能需要额外处理。
- 不支持的应用类型:
- 基于 Web 的应用(比如浏览器里的网页 / 企业 Web 系统):pywinauto 是为本地 Windows 应用设计的,Web 自动化得用 Selenium。
- 自定义渲染引擎的应用(比如 Flutter、React Native 开发的桌面端):这类应用不暴露标准 Windows UI 接口(Win32/UIA),无法被 pywinauto 识别(比如企业微信、部分 Flutter 桌面应用)。
三、安装pywinauto
建议在每个项目的虚拟环境中安装 pywinauto,原因和操作说明如下:
为什么选 “每个项目的虚拟环境”?
- 避免版本冲突:不同项目可能需要不同版本的 pywinauto(比如有的项目用 0.6.9,有的用更新版本),虚拟环境能隔离各项目的依赖。
- 保持项目独立性:项目迁移 / 分享时,虚拟环境的依赖清单(如
requirements.txt)可以精准复现环境,不会受全局 Python 包的影响。
什么情况适合 “全局安装”?
如果你的所有项目都用相同版本的 pywinauto,且不需要隔离依赖,也可以全局安装(但不推荐,容易踩版本冲突的坑)。
步骤 1:打开项目后配置虚拟环境

!!!!!注意:每个项目的虚拟环境不要放一起,单独创建在该项目的目录下,如上图

这个选项的作用是:打开终端时自动激活当前项目目录下的虚拟环境
即便开启了 “Activate virtualenv”,仍加载之前项目的虚拟环境,是因为PyCharm 终端的 “会话缓存” 未清空,具体原因及解决:
1. 终端会话的缓存残留
PyCharm 的终端会保留上一次关闭时的会话状态(包括激活的虚拟环境),即使开启了自动激活,若上次会话的环境未关闭,新打开的终端会继承该状态。
2. 解决:重置终端会话
- 方法 1:关闭当前终端标签页,重新打开一个新的终端标签(新标签会触发自动激活逻辑);
- 方法 2:在终端中执行
deactivate后,重启 PyCharm,再打开终端。
新终端会优先执行 “Activate virtualenv” 的逻辑,自动激活当前项目的.venv,不会再加载之前的环境。
!!!!!!注意:必须选对和当前项目匹配的解释器,否则会出现环境不对应的问题:
![]()
步骤 2:在 PyCharm 里安装 pywinauto
pip install pywinauto==0.6.9 -i https://pypi.tuna.tsinghua.edu.cn/simple
四、UISpy 工具的核心作用
UISpy 是微软提供的 UI 自动化测试工具,用于定位 GUI 程序的 UI 元素(类似 Web 自动化中的开发者工具),是编写 GUI 自动化脚本的前提 —— 只有定位到 UI 元素,才能对其执行操作。
1.UISpy 的功能与适用场景
- 功能:可视化查看应用的 UI 结构(控件树)、元素属性(如名称、类名、坐标),辅助选择 UI 元素并模拟操作;
- 适用范围:仅支持传统 Windows 原生应用框架的程序(如记事本);若工具无法识别元素(如企业微信),则该程序不支持
pywinauto自动化。

2.同类工具
除 UISpy 外,还有 Spy++、Inspect.exe 等,功能与操作逻辑基本一致。
GUI⾃动化简单⽰例
⽰例:打开电脑⾃带记事本,输⼊内容,并保存⽂件。
import time
from pywinauto.application import Application
from pywinauto.timings import wait_until_passes
NOTEPAD_PID = 37884 # 替换为实际PID
# 1. 连接进程并获取窗口
app = Application(backend="win32").connect(process=NOTEPAD_PID)
notepad = app.window()
notepad.set_focus()
time.sleep(2)
# 2. 定位新版记事本输入控件(RichEditD2DPT)
# 增加超时等待,避免控件未加载完成
edit_control = wait_until_passes(
timeout=10, # 超时10秒
retry_interval=1,
func=lambda: notepad.child_window(class_name="RichEditD2DPT")
)
# 3. 输入文本
edit_control.type_keys("这是GUI自动化输入的内容")
time.sleep(1)
# 4. 快捷键保存+关闭
notepad.type_keys("^s") # Ctrl+S
time.sleep(1)
notepad.type_keys("%{F4}") # Alt+F4
| 后端类型 | 适配场景 | 稳定性 | 推荐度 |
|---|---|---|---|
| Win32 | 所有系统记事本(Win7/10/11) | ✅ 99% 稳定 | ⭐⭐⭐⭐⭐(优先选) |
| UIA | 现代应用(如 Office、浏览器) | ❌ 对记事本兼容差 | ⭐⭐(仅特殊场景用) |
五、pywinauto常⻅操作
1.打开程序:2 种方式(启动新程序 / 连接已有程序)
1. 启动新应用程序(start()方法)
- 作用:启动一个全新的 Windows 应用进程。
- 参数:
cmd_line是必填项,需要传入应用的 “可执行文件路径”(支持相对 / 绝对路径)。- 示例:
- 简单启动:
Application(backend="uia").start("notepad.exe")(系统自带程序可直接写文件名) - 绝对路径启动:
start("D:\\software\\Sublime Text 3\\sublime_text.exe")(第三方程序需指定完整路径)
- 简单启动:
- 示例:
2. 连接已有应用程序(connect()方法)
- 作用:关联已经在运行的应用进程(无需重新启动)。
- 参数:只需传 1 个标识参数,常用的有:
process:应用的进程 ID(PID,可通过任务管理器查看)handle:窗口句柄(系统给每个窗口分配的唯一标识)
- 示例:
- 通过 PID 连接:
app = Application(backend="uia").connect(process=31528) - 通过句柄连接:
app = Application(backend="uia").connect(handle=65552)
- 通过 PID 连接:
start和connect的核心区别
| 方法 | 作用 | 返回值 | 适用场景 |
| start() | 启动全新的应用进程 | 绑定该新进程的 Application 实例 | 需打开一个未运行的新程序(如启动空白记事本) |
| connect() | 关联已在运行的应用进程 | 绑定该已有进程的 Application 实例 | 程序已手动 / 自动打开,仅需关联操作(如关联已打开的 “软件测试.txt”) |
2.定位窗口:2 种核心方法
定位窗口是操作控件的前提,pywinauto 提供了 “显式定位”(推荐)和“动态属性定位”(不推荐) 两种方式。
方法 1:通过window()方法显式定位(推荐)
-
作用:通过窗口的特征参数(标题、类名等)精准定位窗口。
-
常用参数(可组合使用):
| 参数 | 作用 | 示例 |
|---|---|---|
title | 精确匹配窗口标题 | window(title="untitled - Sublime Text") |
title_re | 正则匹配窗口标题(灵活匹配动态标题) | window(title_re=".*Sublime.*")(匹配含 “Sublime” 的标题) |
best_match | 模糊匹配标题(允许轻微差异) | window(best_match="Sublime Text") |
class_name | 精确匹配窗口类名(需提前获取类名) | window(class_name="PX_WINDOW_CLASS") |
class_name_re | 正则匹配窗口类名 | window(class_name_re=".*WINDOW_CLASS") |
-
辅助工具:
print_control_identifiers()方法- 作用:打印窗口及其子控件的所有标识信息(标题、类名、控件类型等),帮助你获取定位参数。
- 示例:
win.print_control_identifiers()(执行后会输出类似截图中的控件树结构)

方法 2:通过动态解析对象属性定位(不推荐)
- 作用:利用 Python 动态属性的特性,直接用 “窗口的 best_match 名称” 作为属性调用。
- 示例:
win = app.Dialog(等价于app.window(best_match='Dialog'))- 含特殊字符的标题:用字典式访问
app['untitled • - Sublime Text (UNREGISTERED)']
- 缺点:属性名不能包含空格、特殊符号,易出错且可读性差,仅适用于简单场景。
补充:简化定位 ——top_window()方法
- 作用:快速获取应用的 “顶级窗口”(应用的主窗口),无需指定参数。
- 注意:仅能获取应用的一个顶级窗口,若应用有多个窗口可能定位错误,属于 “简易但不精准” 的方式。
- 示例:
win = app.top_window() # 获取顶级窗口
win.wait('exists') # 等待窗口加载
3.窗⼝操作
窗口操作方法:功能 + 返回值
表格里的方法分为 “控制类”(改变窗口状态)和“检查类”(查询窗口状态)两类:
| 方法 | 功能描述 | 返回值 |
|---|---|---|
close() | 关闭窗口。 | 无返回值。 |
maximize() | 将窗口最大化。 | 无返回值。 |
minimize() | 最小化窗口 | 无返回值。 |
restore() | 窗口恢复正常大小 | 无返回值。 |
get_show_state() | 获取窗口的显示状态。 | 返回一个整数值,表示窗口的状态:0: 正常1: 最大化2: 最小化 |
is_dialog() | 检查控件是否是顶级窗口。 | 返回布尔值:True 表示是顶级窗口,False 表示不是顶级窗口。 |
is_maximized() | 检查窗口是否处于最大化状态。 | 返回布尔值:True 表示窗口已最大化,False 表示未最大化。 |
is_minimized() | 检查窗口是否处于最小化状态。 | 返回布尔值:True 表示窗口已最小化,False 表示未最小化。 |
is_normal() | 检查窗口是否处于正常状态(既未最小化也未最大化)。 | 返回布尔值:True 表示窗口处于正常状态,False 表示未处于正常状态。 |
4. 定位控件
4.1控件分类:理解桌面应用的控件层级
打开UI对象检查⼯具UISpy,通过ControlType可查看所定位到控件的类型。

桌面应用的控件是分层级的容器结构(窗口→子控件→子子控件),常见控件按功能分为 10 + 类,每类对应不同的交互逻辑:
- 直接从主窗口定位:简单快捷,适合控件属性唯一的场景;
- 逐层从父窗口定位:更精准,适合控件属性重复的场景;
- 层级是 “路径” 不是 “限制”,pywinauto 支持跨层级定位。
| 分类 | 控件名称 | 说明 |
|---|---|---|
| 窗口与对话框 | 对话框 (Dialog) | 用于用户交互(如警告、确认、信息输入) |
| 窗口与对话框 | 窗格 (Pane) | 窗口的组成部分,显示特定内容 / 功能 |
| 输入控件 | 按钮 (Button) | 触发操作(如点击执行功能) |
| 输入控件 | 编辑栏 (Edit) | 输入 / 编辑文本(支持单行 / 多行) |
| 输入控件 | 组合框 (ComboBox) | 结合文本框 + 列表框,支持选择 / 输入自定义值 |
| 输入控件 | 列表框 (ListBox) | 显示可选项目列表(支持单选 / 多选) |
| 菜单控件 | 菜单 (Menu) | 窗口顶部的功能选项集合 |
| 菜单控件 | 菜单项 (MenuItem) | 菜单中的具体选项,点击执行对应功能 |
| 菜单控件 | 弹出菜单 (PopupMenu) | 右键点击弹出的快捷功能菜单 |
| 列表显示控件 | 列表显示控件 (ListView) | 表格形式显示数据(支持多列、排序) |
| 容器控件 | 组框 (GroupBox) | 对控件分组,提升界面可读性 |
| 选择控件 | 复选框 (CheckBox) | 多选操作(可勾选多个选项) |
| 选择控件 | 单选框 (RadioButton) | 互斥选择(只能选一个选项) |
| 显示控件 | 状态栏 (StatusBar) | 窗口底部显示应用状态 / 提示信息 |
| 显示控件 | 静态内容 (Static) | 显示不可编辑的静态文本 / 图像 |
| 导航控件 | 树状视图 (TreeView) | 展示分层数据(如文件结构、组织架构) |
| 导航控件 | 选项卡控件 (TabControl) | 有限空间内组织多个页面,每个选项卡含不同内容 |
| 工具控件 | 工具栏 (Toolbar) | 放置常用按钮 / 工具,方便快速操作 |
| 工具控件 | 工具提示 (ToolTips) | 鼠标悬停时显示控件功能提示 |
| 头部内容 | 头部内容 (Header) | 显示标题 / 表头信息(如表格列标题) |
代码 / 概念
- app = Application(backend="uia").connect(process=QQ音乐PID)
- win = app.window()
对应 QQ 音乐的现实场景
- 你找到并 “绑定” 了 QQ 音乐这个软件进程
- 获取 QQ 音乐的顶级主窗口
通俗解释
- 相当于你走到 QQ 音乐的 “软件本体” 面前,确认 “我要操作的是这个软件,不是其他软件”;但此时你还没接触到它的任何界面(窗口)。
- 相当于你打开了 QQ 音乐的 “主界面”(就是你双击桌面图标后看到的那个大窗口),这个主窗口是所有其他小窗口(比如下载弹窗、设置窗口、歌词窗口)的 “老大”,所有子窗口都归它管。
# 1. 绑定QQ音乐进程(找到“QQ音乐”这个软件)
app = Application(backend="uia").connect(process=QQ音乐的PID)
# 2. 获取QQ音乐的顶级主窗口(打开QQ音乐的主界面)
# 这一步就是拿到“QQ音乐主界面”这个顶级窗口,所有弹窗/子窗口都在它下面
qqmusic_main_win = app.window()
# 3. 操作主窗口下的子窗口(比如定位“下载弹窗”)
# 下载弹窗是主窗口的子窗口,相当于主界面上弹出来的小窗口
download_dialog = qqmusic_main_win.child_window(name="添加本地下载音乐", control_type="Dialog")
# 4. 操作子窗口的子控件(比如“取消”按钮)
# 取消按钮是下载弹窗的子控件,相当于弹窗里的一个按钮
cancel_btn = download_dialog.child_window(name="取消", control_type="Button")
cancel_btn.click_input()
把 QQ 音乐进程比作 “一栋房子”:
app = connect(process=PID):你确认了要进 “QQ 音乐这栋房子”(不是微信、记事本的房子);win = app.window():你走进了房子的 “客厅”(顶级主窗口),客厅是房子的核心区域;child_window():从客厅走到 “卧室”(下载弹窗),再从卧室找到 “床头柜上的按钮”(取消按钮)—— 所有操作都基于 “客厅(顶级窗口)” 这个起点。
定位控件,需要借助前⾯学到的 print_control_identifiers() ⽅法,打印窗⼝及其⼦控件的标识符信息
Dialog - 'untitled • - Sublime Text (UNREGISTERED)' (L806, T81, R1811,
B1007)
['Dialog', 'untitled • - Sublime Text (UNREGISTERED)Dialog', 'untitled • -
Sublime Text (UNREGISTERED)']
child_window(title="untitled • - Sublime Text (UNREGISTERED)",
control_type="Window")
|
| ScrollBar - '' (L815, T44, R915, B54)
| ['ScrollBar', 'ScrollBar0', 'ScrollBar1']
| |
| | Button - '左移⼀列' (L0, T0, R0, B0)
| | ['左移⼀列', 'Button', '左移⼀列Button', 'Button0', 'Button1']
| | child_window(title="左移⼀列", auto_id="UpButton",
control_type="Button")
| |
| | Thumb - '位置' (L0, T0, R0, B0)
| | ['Thumb', '位置', '位置Thumb', 'Thumb0', 'Thumb1', '位置0', '位置1',
'位置Thumb0', '位置Thumb1']
| | child_window(title="位置", auto_id="ScrollbarThumb",
control_type="Thumb")
| |
| | Button - '右移⼀列' (L0, T0, R0, B0)
| | ['右移⼀列Button', '右移⼀列', 'Button2']
| | child_window(title="右移⼀列", auto_id="DownButton",
control_type="Button")
|
| ScrollBar - '' (L715, T144, R725, B244)
| ['ScrollBar2']
| |
| | Button - '上⼀⾏' (L0, T0, R0, B0)
| | ['上⼀⾏', '上⼀⾏Button', 'Button3']
| | child_window(title="上⼀⾏", auto_id="UpButton",
control_type="Button")
| |
| | Thumb - '位置' (L0, T0, R0, B0)
| | ['Thumb2', '位置2', '位置Thumb2']
| | child_window(title="位置", auto_id="ScrollbarThumb",
control_type="Thumb")
| |
| | Button - '下⼀⾏' (L0, T0, R0, B0)
| | ['下⼀⾏', '下⼀⾏Button', 'Button4']
| | child_window(title="下⼀⾏", auto_id="DownButton",
control_type="Button")
|
| TitleBar - '' (L835, T84, R1802, B119)
| ['TitleBar']
| |
| | Menu - '系统' (L652, T72, R674, B94)
| | ['Menu', '系统Menu', '系统', '系统0', '系统1', 'Menu0', 'Menu1']
| | child_window(title="系统", auto_id="MenuBar", control_type="MenuBar")
| | |
| | | MenuItem - '系统' (L652, T72, R674, B94)
| | | ['系统2', 'MenuItem', '系统MenuItem', 'MenuItem0', 'MenuItem1']
| | | child_window(title="系统", control_type="MenuItem")
| |
| | Button - '最⼩化' (L1624, T82, R1684, B119)
| | ['最⼩化Button', '最⼩化', 'Button5']
| | child_window(title="最⼩化", control_type="Button")
| |
| | Button - '最⼤化' (L1684, T82, R1743, B119)
| | ['最⼤化', 'Button6', '最⼤化Button']
| | child_window(title="最⼤化", control_type="Button")
......
......
注意:
print_control_identifiers() 方法默认只能打印 “当前可见窗口 / 控件” 的标识信息—— 比如 Sublime 的 File 菜单,只有当 File 菜单被展开(可视化显示)时,它的子菜单(New/Open 等)才会被该方法捕获并打印。
如果要获取 File 的子菜单标识,需要先通过代码展开 File 菜单窗口,再对这个展开的子菜单窗口调用print_control_identifiers(),才能打印出子菜单的控件信息。
| 操作场景 | 操作步骤 | print_control_identifiers() 打印内容 |
|---|---|---|
| 仅打开Sublime主窗口 | 直接调用主窗口的该方法 | 主窗口+可见的顶层菜单(File/Edit等) |
| 要获取File的子菜单 | 1. 定位并展开File菜单窗口 2. 调用该子窗口的方法 | File菜单下的子菜单(New/Open/Save等) |
注意:

| 定位写法类型 | 具体示例 | 特点 & 使用场景 |
|---|---|---|
| 别名/快捷定位 | win['File'] 或 win['FileMenuItem'] 或 win['MenuItem21'] | 1. 最简单:直接用打印结果里[]中的任意一个字符串就能定位2. 原理:自动化库会自动匹配控件的“名称/别名” 3. 缺点:如果有重名控件,可能定位错 |
| 精准属性定位 | win.child_window(title="File", control_type="MenuItem") | 1. 最精准:通过title(标题)+control_type(控件类型)双重条件定位2. 原理:指定控件的具体属性,缩小匹配范围 3. 优点:即使有重名控件,也能准确定位目标 |
打印结果里同时给出这两种信息,是为了:
['File', 'FileMenuItem', 'MenuItem21']→ 给你快捷写法,日常调试 / 简单场景用,省代码;child_window(...)→ 给你精准写法,正式脚本 / 复杂界面用,避免定位错误。
# 方式1:快捷别名定位(任选其一)
file_menu1 = win['File']
file_menu2 = win['FileMenuItem']
# 方式2:精准属性定位(推荐正式脚本用)
file_menu3 = win.child_window(title="File", control_type="MenuItem")
# 三种方式定位的是同一个控件,点击效果完全一样
file_menu3.click()
简单说:简单场景用 [] 里的快捷名,复杂场景用 child_window 的精准属性,两种都能用,精准写法更稳
注意:打印菜单 / 控件标识,核心不是重复 UI 工具的工作,而是:
| 对比维度 | UI工具(UIgoon/Inspect.exe) | 代码打印print_control_identifiers() |
|---|---|---|
| 信息来源 | 系统层面抓取的控件元数据(偏“理论值”) | 自动化库实际识别到的控件信息(偏“实际值”) |
| 准确性 | ❌ 可能不准: 1. 部分自定义控件识别不到 2. 属性与自动化库兼容度低 3. 易受版本影响 | ✅ 最准确: 1. 输出自动化库可识别的属性 2. 反映控件真实加载状态 3. 是代码定位的直接依据 |
| 适用场景 | 快速预览控件结构、初步定位(辅助作用) | 编写自动化代码时,获取可用的控件标识(核心作用) |
| 局限性 | 无法反映“自动化库是否识别控件”,可能出现“工具可见但代码定位不到”的情况 | 仅能打印当前加载的控件,未加载的临时控件无法捕获 |
- 验证兼容性:确认 UI 工具显示的控件信息,是否能被你用的自动化库(如 pywinauto)识别;
- 获取精准标识:直接拿到代码能 “直接用” 的控件属性(比如
title/control_type),避免因 UI 工具的 “理论值” 导致代码定位失败; - 排查定位问题:如果代码定位不到控件,打印出来的信息是最直接的排查依据(比如能看到控件是否真的存在、属性名是否和预期一致)。
简单说:UI 工具是 “参考地图”,打印的信息是 “实际能走的路”—— 自动化代码要按 “实际的路” 来写,才不会走偏
4.2动态解析
基于best_match标题来定位
⽰例1:定位sublimeText⼯具的菜单栏
from pywinauto import Application
app = Application(backend="uia").connect(process=34408)
win = app.window(title_re=".*Sublime Text.*")
win.wait('exists')
win.restore()
menu = win['应⽤程序']
print(menu.items())
4.3child_window
child_window() 和定位窗⼝的⽅法 window() 参数⼀样,可以通过标题或者类名进⾏精确匹 配、模糊匹配等,在这⾥额外拓展⼏个进⾏控件定位时需要⽤到的参数:

from pywinauto import Application
# 创建Application对象,连接到正在运⾏的Sublime Text进程
app = Application(backend='uia').connect(process=38544)
# 获取与Sublime Text相关的窗⼝对象,使⽤正则表达式匹配窗⼝标题
win = app.window(title_re='.*Sublime Text.*')
# 等待窗⼝变为可⻅状态,确保窗⼝已经加载完成
win.wait("visible")
# 通过控件的属性(标题、⾃动ID和控件类型)定位菜单栏对象
menu = win.child_window(title="应⽤程序", auto_id="MenuBar",
control_type="MenuBar")
# 打印菜单项的列表,查看菜单中包含的所有选项
print(menu.items())
若存在多个控件的 auto_id 相同,可通过添加索引参数来定位:
from pywinauto import Application
app = Application(backend='uia').connect(process=38544)
win = app.window(title_re='.*Sublime Text.*')
win.wait("visible")
#存在相同的auto_id和control_type,使⽤found_index来定位
menu = win.child_window(auto_id="MenuBar",
control_type="MenuBar",found_index=1)
print(menu.texts())
注意,若元素值为空,或不是唯⼀的情况下,都会导致定位失败
⽰例:定位失败
from pywinauto import Application
app = Application(backend='uia').connect(process=38544)
win = app.window(title_re='.*Sublime Text.*')
win.wait("visible")
#存在相同的auto_id和control_type
menu = win.child_window(auto_id="MenuBar", control_type="MenuBar")
print(menu.texts())

控件之间存在⽗⼦关系,可通过 children() ⽅法获取控件的⼦类,也可通过 parent() ⽅法获取控件的⽗类
更多推荐
所有评论(0)