一、安装与工具

安装

pip install pywinauto==0.6.9

UI 对象检查工具(定位元素用)

工具 说明
UISpy 微软官方工具,推荐使用
Inspect.exe Windows SDK 自带
Spy++ Visual Studio 自带

判断能否用 pywinauto 自动化:用 UISpy 能定位到元素 → 可以;不能定位 → 不能用(如企业微信、Flutter应用)。


二、两种后端模式(backend)

模式 适用场景
win32 传统 MFC、VB6 等旧架构应用
uia 现代 WinForms、WPF、Qt5 应用(推荐
from pywinauto.application import Application
​
# 启动应用
app = Application(backend="uia").start("notepad.exe")
​
# 连接已运行的应用
app = Application(backend="uia").connect(process=12345)
app = Application(backend="uia").connect(title="QQMusic")

三、定位窗口

window() 方法参数

参数 说明 示例
title 精确匹配标题 title="计算器"
title_re 正则匹配 title_re=".*Sublime.*"
class_name 窗口类名 class_name="Notepad"
best_match 模糊匹配 best_match="untitled"
win = app.window(title_re=".*Sublime Text.*")
win.wait("visible")  # 等待窗口可见

快速获取顶级窗口

win = app.top_window()  # 不一定准确,谨慎使用

四、等待机制(重要!)

GUI 行为不稳定,必须加等待。

wait() / wait_not()

win.wait("exists")     # 窗口句柄有效
win.wait("visible")    # 窗口可见
win.wait("enabled")    # 控件未禁用
win.wait("ready")      # 可见且启用
win.wait("active")     # 窗口处于活动状态
​
win.wait_not("visible") # 等待窗口消失

wait_until()

from pywinauto.timings import wait_until
wait_until(10, 2, lambda: win.is_visible(), True)  # 10秒超时,每2秒检查一次

五、定位控件

child_window() 方法

参数 说明
title / title_re 标题/正则匹配
auto_id 自动化 ID(最稳定)
control_type 控件类型(Button、Edit、List等)
found_index 同属性多个控件时指定索引
# 基本定位
edit = win.child_window(auto_id="searchBox", control_type="Edit")
​
# 多个相同控件时用索引
btn = win.child_window(auto_id="MenuBar", control_type="MenuBar", found_index=1)

打印控件树(调试利器)

win.print_control_identifiers()  # 打印所有子控件信息

动态解析(不推荐,有空格时用)

win['应用程序']  # 等价于 win.child_window(best_match='应用程序')

六、控件操作

点击操作

方法 说明
click_input() 鼠标左键单击
right_click_input() 右键单击
double_click_input() 双击
btn.click_input()

文本操作

方法 说明
texts() 返回所有文本(列表)
window_text() 返回主文本(字符串)
print(win.window_text())        # 窗口标题
print(btn.window_text())        # 按钮文字

键盘输入

# 方式1:type_keys(推荐,直接作用于控件)
edit.type_keys("Hello World")
edit.type_keys("换行{ENTER}", with_newlines=True)
edit.type_keys("带空格", with_spaces=True)

# 特殊按键
edit.type_keys("{ENTER}")       # 回车
edit.type_keys("{TAB}")         # Tab
edit.type_keys("{BACKSPACE}")   # 退格
edit.type_keys("{ENTER 2}")     # 按两次回车

# 转义特殊字符
edit.type_keys("1{+}2=3")       # 正确显示 "1+2=3"

# 方式2:全局键盘(不推荐,依赖焦点)
from pywinauto.keyboard import send_keys
send_keys("123")

七、鼠标操作(mouse 模块)

from pywinauto import mouse

# 获取控件位置
rect = btn.rectangle()           # 返回矩形 (top,left,right,bottom)
mid_point = btn.rectangle().mid_point()  # 返回中心坐标 (x, y)

# 鼠标操作
mouse.click(coord=(x, y))                    # 左键单击
mouse.double_click(coord=(x, y))             # 双击
mouse.right_click(coord=(x, y))              # 右键单击
mouse.scroll(coord=(x, y), wheel_dist=-500)  # 滚动(负=向下,正=向上)
mouse.move(coord=(x, y))                     # 移动鼠标

八、窗口操作

方法 说明
close() 关闭窗口
maximize() / minimize() 最大化/最小化
restore() 恢复正常大小
set_focus() 设置焦点到窗口
is_maximized() / is_minimized() 检查状态
win.minimize()
win.restore()
win.set_focus()

九、菜单操作

获取菜单项

menu = win['应用程序']           # 或 win.child_window(title="应用程序")
items = menu.items()            # 获取所有菜单项
item = menu.item_by_index(0)    # 按索引获取

点击菜单路径

# 方法1:item_by_path
menu.item_by_path("File -> Save").click_input()

# 方法2:menu_select(更简洁)
win.menu_select("File -> Save")

多层菜单(需要定位子窗口)

# 点击 File -> Open Recent
menu.item_by_path("File -> Open Recent").click_input()

# 定位到 Open Recent 子窗口
openRecent_win = win.child_window(title="Open Recent", control_type="Window")
clear_item = openRecent_win.child_window(title="Clear Items", control_type="MenuItem")
clear_item.click_input()

十、列表控件操作

方法 说明
get_items() 获取所有列表项
item_count() 获取列表项数量
get_item(row=0) 获取指定行项目
list_ctrl = win.child_window(auto_id="HomeListView", control_type="List")

# 获取数量
count = list_ctrl.item_count()

# 获取第一项
first_item = list_ctrl.get_item(row=0)

# 获取所有项
all_items = list_ctrl.get_items()

十一、常见自动化场景模板

1. 启动/连接应用 + 完整流程

from pywinauto import Application
from pywinauto import mouse
import time

# 启动应用
app = Application(backend="uia").start("D:\\app\\QQMusic.exe")

# 或连接已运行的应用
app = Application(backend="uia").connect(process=12345)

# 定位主窗口
win = app.window(title="QQMusic")
win.wait("visible")

# 定位控件并操作
search_box = win.child_window(auto_id="searchBox", control_type="Edit")
search_box.click_input()
search_box.type_keys("周杰伦")

# 点击搜索按钮
search_btn = win.child_window(title="搜索", control_type="Button")
search_btn.click_input()

# 验证结果
result_list = win.child_window(control_type="List")
assert result_list.item_count() > 0

# 关闭应用
win.close()

2. 带夹具(fixture)的测试类

import pytest
from pywinauto import Application

@pytest.fixture(scope="session")
def app():
    app = Application(backend="uia").start("notepad.exe")
    win = app.window(title_re=".*Notepad")
    win.wait("visible")
    yield app
    win.close()

def test_notepad_input(app):
    win = app.window(title_re=".*Notepad")
    edit = win.child_window(control_type="Document")
    edit.type_keys("Hello Pywinauto!")
    assert "Hello" in edit.window_text()

十二、注意事项与最佳实践

要点 说明
优先用 auto_id 最稳定,不受界面文字变化影响
必须加等待 GUI 行为不稳定,wait() 是必须的
不要用 __init__ pytest 测试类中不能用 __init__,用 fixture
鼠标操作优先用控件方法 能用 click_input() 就不用 mouse.click()
多层菜单需逐层定位 子菜单可能在新窗口中
列表验证用数量变化 验证新增/删除操作时,检查 item_count 变化

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐