Python uiautomation模块实战指南

uiautomation

1. 引言

目的: 本指南旨在为想要使用Python进行Windows应用程序自动化的人士提供全面的学习资源。无论你是新手还是有一定经验的开发者,都能从中找到有价值的信息。

概述: uiautomation 是一个强大的Python库,用于与基于Microsoft UI Automation(UIA)框架的应用程序交互。它可以帮助你自动化日常任务、执行软件测试或创建辅助工具。

https://github.com/yinkaisheng/Python-UIAutomation-for-Windows

2. 环境搭建

系统要求:

  • Windows操作系统(推荐Windows 7及以上)
  • Python 3.x(建议使用最新稳定版本)
  • 安装方法: 通过pip安装是最简单的方法:

    pip install uiautomation
    

    3. 基础概念

    UI Automation: UI Automation是微软提供的技术,允许程序以编程方式访问和操作用户界面元素。uiautomation库利用了这一技术来实现对Windows应用的控制。

    控件树: 每个Windows应用程序都有一个由各种控件组成的层次结构。uiautomation可以通过遍历这个树状结构来查找特定的控件。

    关键术语:

  • Control:代表UI中的一个元素, 一个控件类型。
  • Pattern:定义了一组可以应用于控件的操作接口,如ValuePattern、InvokePattern等。
  • 4. uiautomation常用方法

    1. Click() -> None

    2. 含义:该方法用于模拟鼠标点击操作,通常用于按钮、链接或其他可点击的UI元素。
    3. import uiautomation as uia
      uia.Click(x=10, y=10) # 鼠标点击坐标(10, 10)
      
    4. SendKeys() -> None

  • 含义:此方法用于向活动窗口或控件发送键盘输入,可以用来填充文本框或者触发快捷键等。。
  • import uiautomation as uia
    
    uia.SendKeys("xxxx")  # 输入文本xxxx
    uia.SendKeys("{Ctrl}c")  # 按快捷键 Ctrl +c
    uia.SendKeys('0123456789{Enter}')  # 输入文本0123456789后按Enter键
    
    1. ShowWindow(handle: int, cmdShow: int) -> bool

    2. 含义:用来显示或隐藏指定的应用程序窗口。此方法不一定能确保窗口被带到最前并且获得焦点
    3. 参数
    4. handle: 控件句柄
    5. cmdShow: 执行的操作,0123、或者4
    6. window = uia.WindowControl(SubName="PN")
      print(window.NativeWindowHandle) #返回控件句柄
      uia.ShowWindow(window.NativeWindowHandle, 4)  # 以最近一次的大小和状态显示窗口
      uia.ShowWindow(window.NativeWindowHandle, 3)  # 将窗口最大化
      uia.ShowWindow(window.NativeWindowHandle, 2)  # 将窗口最小化
      uia.ShowWindow(window.NativeWindowHandle, 1)  # 将窗口窗口化
      uia.ShowWindow(window.NativeWindowHandle, 0)  # 隐藏窗口
      
    7. WaitForExist(control: Control, timeout: float) -> bool

    8. 含义:等待某个特定的UI元素出现。如果在设定的时间内找到了这个元素,则返回True;否则返回False。
    9. 参数
    10. control: 控件对象
    11. timeout: 等待时间
    12. import uiautomation as uia
      
      window = uia.WindowControl(SubName="PN")
      print(uia.WaitForExist(window, 10))  # 10s内等待window窗口出现
      
    13. WaitForDisappear(control: Control, timeout: float) -> bool

    14. 含义**:等待某个特定的UI元素消失。如果在设定的时间内该元素确实消失了,则返回True;反之则返回False。
    15. 参数
    16. control: 控件对象
    17. timeout: 等待时间
    18. import uiautomation as uia
      
      window = uia.WindowControl(SubName="PN")
      print(uia.WaitForDisappear(window, 10))  # 10s内等待window窗口消失
      
    19. ShowDesktop() -> None

    20. 含义:模拟按下“显示桌面”的功能,最小化所有打开的窗口以展示桌面。
    21. import uiautomation as uia
      
      uia.ShowDesktop()
      
    22. GetRootControl() -> Control

    23. 含义:获取当前桌面的根控件对象。这通常是整个屏幕或者最顶层窗口的对象,从这里可以遍历找到其他子控件。
    24. import uiautomation as uia
      
      root = uia.GetRootControl()  # 桌面控件
      for con in root.GetChildren():
      	print(con)
      
    25. GetScreenSize() -> Tuple[int, int]:

    26. 含义:返回屏幕的尺寸大小。
    27. import uiautomation as uia
      print(uia.GetScreenSize())
      

    5. Control常用类型

    类型 控件解释
    WindowControl 程序窗口
    ButtonControl 按钮
    TextControl 文本显示
    EditControl 编辑框
    MenuControl 菜单
    MenuItemControl 菜单选项
    RadioButtonControl 单选框
    CheckBoxControl 勾选框

    6. Control常用属性

    1. Name(self) -> str
    2. 含义:控件的名称或标签文本。
    3. 用途:用于标识和查找控件。
    4. ControlTypeName(self) -> str
    5. 含义:控件类型名称,如按钮、编辑框、窗口等。
    6. 用途:帮助区分不同类型的控件。
    7. ClassName(self) -> str
    8. 含义:控件的类名,通常与控件的具体实现有关。
    9. 用途:辅助查找特定类型的控件。
    10. AutomationId(self) -> str
    11. 含义:控件的自动化ID,是一个唯一的标识符。
    12. 用途:用于更精确地定位控件。
    13. BoundingRectangle(self) -> Rect
    14. 含义:控件在屏幕上的边界矩形,包含 left, top, right, bottom 属性。
    15. 用途:获取控件的位置和尺寸,用于点击、截图等操作。
    16. IsEnabled(self) -> bool
    17. 含义:控件是否启用(可交互)。
    18. 用途:判断控件是否可以被用户操作。
    19. IsOffscreen (self) -> bool
    20. 含义:控件是否位于屏幕之外(不可见)。
    21. 用途:检查控件是否超出当前视图范围。

    7. Control常用方法及解释

    1. Exists(self) -> bool

    2. 含义:检查控件是否存在于UI树中。
    3. 参数
    4. maxSearchSeconds: 可选的超时时间(秒),用于等待控件出现,默认为5。
    5. 用途:确保在执行其他操作之前,控件确实存在。
    6. Click(self) -> None

    7. 含义:模拟鼠标点击控件。
    8. 参数
    9. ratioX, ratioY: 点击位置相对于控件宽度和高度的比例(默认为中心)。
    10. x, y: 绝对坐标(像素),相对于控件左上角的位置。
    11. simulateMove: 这个布尔值参数决定了在执行点击动作时,鼠标指针移动到目标坐标点的方式
    12. 用途:用于触发按钮点击或其他需要鼠标交互的操作。
    13. DoubleClick(self) -> None

    14. 含义:模拟双击控件。
    15. 参数:同 Click() 方法。
    16. 用途:用于需要双击激活的功能。
    17. RightClick(self) -> None)

    18. 含义:模拟右键点击控件。
    19. 参数:同 Click() 方法。
    20. 用途:用于调出上下文菜单等操作。
    21. DragDrop(self) -> None

    22. 含义:拖放控键,可以用来模拟用户移动窗口,或者拖拽窗口大小动作。
    23. 参数:
    24. x1, y1: 点击控件的绝对位置。
    25. x2, y2: 释放目标坐标的绝对位置。
    26. moveSpeed: 移动速度(秒)。
    27. 用途:用于实现拖拽操作。
    28. SendKeys(self) -> None

    29. 含义:向控件发送键盘输入。可以发送文本,也可以发送按键
    30. 参数:
    31. text: 要发送的字符串或按键组合(例如 '{CTRL}a' 表示Ctrl+A,)。
    32. interval:浮点数,按键之间的秒数。
    33. waitTime: 发送后等待的时间(秒)。
    34. 用途:用于文本输入或发送快捷键命令。
    35. SetFocus(self) -> bool

    36. 含义:将焦点设置到该控件上。
    37. 用途:确保后续操作针对正确的目标控件。
    38. SetActive(self) -> bool

    39. 含义:将窗口设为前台活动窗口。
    40. 用途:使窗口成为当前活动窗口,以便接收输入。
    41. SetTopMost(filename)

    42. 含义:置顶窗口。
    43. 用途:置顶目标窗口,便于操作该窗口。
    44. GetTopLevelControl(self) -> Optional[‘Control’]

    45. 含义:获取当前控件所放置的顶级控件。
    46. 用途:获取最前面的控件。

    8. Pattern常用接口

    Pattern 类提供了对控件行为的访问,例如滚动、选择、值变化等。每个模式都对应着一组方法、属性和事件,它们描述了控件能够执行的操作。以下是一些常见的 UIAutomation 模式:

    1. InvokePattern
  • 含义: InvokePattern 通常用于模拟用户对控件的“调用”或“激活”操作。当用户点击按钮时,他们实际上是在“调用”该按钮所代表的功能。在自动化测试或者辅助技术中,InvokePattern 允许开发者通过代码来触发这些相同的用户交互行为。

  • 常用方法

  • Invoke(self, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 用于点击支持InvokePattern的控件

  • 用法

    import uiautomation as uia
    target_control = uia.ButtonControl()
    target_control.GetInvokePattern().Invoke()
    
  • 2. SelectionPattern
  • 含义:SelectionPattern 提供了对多选或多选项目选择状态的访问。这个模式允许自动化客户端控制支持选择功能的控件(如列表框、组合框、树形控件等),并可以获取当前的选择信息。

  • 常用方法

  • GetSelection(self) -> List[‘Control’]

  • 用途: 用于获取已选择的控件列表

  • 用法:

    target_control = uia.ComboBoxControl()
    print(target_control.GetSelectionPattern().GetSelection())
    
  • 3. ValuePattern
  • 含义:ValuePattern允许获取或设置支持该模式的控件的值。例如,它可以用于文本框、滑块、旋钮等控件来读取当前值或者设置新值。

  • 常用属性

  • IsReadOnly(self) -> bool

  • 用途: 判断该值是否为只读(即用户不能修改

  • 用法:

    target_control = uia.DocumentControl(Name="文本编辑器")
    print(target_control.GetValuePattern().IsReadOnly)
    
  • Value(self) -> str

  • 用途: 获取控件的当前值

  • 用法:

    target_control = uia.DocumentControl(Name="文本编辑器")
    print(target_control.GetValuePattern().Value)
    
  • 常用方法

  • SetValue(self, value: str, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 设置控件的新值

  • 用法:

    target_control = uia.DocumentControl(Name="文本编辑器")
    print(target_control.GetValuePattern().SetValue("New Text"))
    
  • 4. ExpandCollapsePattern
  • 含义: ExpandCollapsePattern 是 UIAutomation 框架中的一个模式,它允许控制和获取支持展开或折叠行为的控件的状态。例如,它可以用于树节点、菜单项、组合框等控件来展开或折叠它们的内容。

  • 常用属性

  • ExpandCollapseState(self) -> int

  • 用途: 获取当前控件的展开或折叠状态。

  • 用法:

    target_control = uia.TreeItemControl(Name="电池")
    print(target_control.GetExpandCollapsePattern().ExpandCollapseState)
    
  • 常用方法

  • Collapse(self, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 将当前控件设置为折叠状态。

  • 用法:

    target_control = uia.TreeItemControl(Name="电池")
    target_control.GetExpandCollapsePattern().Collapse()
    
  • Expand(self, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 将当前控件设置为展开状态。

  • 用法:

    target_control = uia.TreeItemControl(Name="电池")
    target_control.GetExpandCollapsePattern().Expand()
    
  • 5. TogglePattern
  • 含义: TogglePattern ,它允许获取和设置支持切换状态的控件的状态。此模式适用于可以在这几种状态之间切换的控件,例如复选框、开关(toggle switches)、单选按钮等。

  • 常用属性:

  • ToggleState(self) -> int

  • 用途: 获取当前控件勾选状态。

  • 用法:

    target_control = uia.CheckBoxControl(Name="Install")
    print(target_control.GetTogglePattern().ToggleState)
    
  • 常用方法:

  • Toggle(self, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 切换控件勾选状态。

  • 用法:

    target_control = uia.CheckBoxControl(Name="Install")
    target_control.GetTogglePattern().Toggle()  # 切换状态
    
  • 6. TextPattern
  • 含义TextPattern 提供了对文本控件的访问和操作。这个模式允许自动化客户端读取、编辑和导航文本内容,适用于支持丰富文本编辑功能的控件,如文本框、富文本编辑器等。

  • 常用属性

  • DocumentRange(self) -> TextRange

  • 用途: 获取表示整个文档范围的 TextRange 对象。

  • 返回值: 返回一个 TextRange 对象,代表整个文档的内容。

  • 用法:

    target_control = uia.DocumentControl()
    print(target_control.GetTextPattern().DocumentRange.GetText())
    
  • 7. WindowPattern

    WindowPattern 是 UIAutomation 框架中的一个模式,它提供了对窗口控件的控制。通过 WindowPattern,自动化客户端可以获取窗口的状态信息、最大化、最小化、关闭窗口以及设置窗口的可见性。

  • 常用属性

  • CanMaximize(self) -> bool

  • 用途: 获取当前窗口是否支持最大化。

  • 返回值: 如果窗口支持最大化,则返回 True;否则返回 False

  • 用法:

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().CanMaximize)
    
  • CanMinimize(self) -> bool

  • 用途: 获取当前窗口是否支持最小化。

  • 返回值: 如果窗口支持最小化,则返回 True;否则返回 False

  • 用法

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().CanMinimize)
    
  • IsModal(self) -> bool

  • 用途: 获取当前窗口是否为模态窗口(即在该窗口关闭之前用户无法与其它窗口交互)。

  • 返回值: 如果窗口是模态窗口,则返回 True;否则返回 False

  • 用法

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().IsModal)
    
  • IsTopmost(self) -> bool

  • 用途: 获取当前窗口是否始终位于顶层。

  • 返回值: 如果窗口始终位于顶层,则返回 True;否则返回 False

  • 用法

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().IsTopmost)
    
  • WindowVisualState(self) -> int

  • 用途: 获取当前窗口的视觉状态。

  • 返回值:

  • 0: 窗口处于正常状态。
  • 1: 窗口已最大化。
  • 2: 窗口已最小化。
  • 用法

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().WindowVisualState)
    
  • 常用方法

  • Close(self, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 发送关闭请求给窗口。

  • 返回值: 返回 True 表示操作成功,否则返回 False

  • 用法:

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().Close())
    
  • SetWindowVisualState(self, state: int, waitTime: float = OPERATION_WAIT_TIME) -> bool

  • 用途: 设置窗口的视觉状态(最大化、最小化、恢复正常),将窗口带到最前并且获得焦点,。

  • 参数:

  • state: 新的窗口视觉状态,取值为 0, 1, 或 2
  • 返回值: 返回 True 表示操作成功,否则返回 False

  • 用法:

    target_control = uia.WindowControl(SubName="设备管理器")
    print(target_control.GetWindowPattern().SetWindowVisualState(0)) # 窗口化
    print(target_control.GetWindowPattern().SetWindowVisualState(1)) # 最大化
    print(target_control.GetWindowPattern().SetWindowVisualState(2)) # 最小化
    
  • 9. 常用的点击方法

    uiautomation.Click()					# 单击控件
    uiautomation.DoubleClick()				# 双击控件
    uiautomation.RightClick()				# 单击右键
    uiautomation.MiddleClick()				# 点击鼠标中键(滚轮)
    

    上面的点击方法默认点击控件的中心点,如果点击控件的其他位置可以传递不同的参数

  • x: int

    含义:x 是整数,表示点击点相对于控件左右侧的绝对坐标(以像素为单位)。
    如果x>0, 表示横向方向上的偏移量,从控件最左侧边缘开始计算,向右偏移
    如果x<0, 表示横向方向上的偏移量,从控件最右侧边缘开始计算,向左偏移 
    
  • y: int

    含义:y 是整数,表示点击点相对于控件上下侧的绝对坐标(以像素为单位)。
    如果y>0, 表示纵向方向上的偏移量,从控件最上侧边缘开始计算,向下偏移
    如果y<0, 表示纵向方向上的偏移量,从控件最下侧边缘开始计算,向上偏移 
    
  • ratioX: float

    含义:ratioX 是一个浮点数,表示点击点相对于控件宽度的比例位置。它的取值范围是 0 到 1。
    0 表示点击点位于控件的最左侧边缘。
    1 表示点击点位于控件的最右侧边缘。
    0.5(默认值)表示点击点位于控件的水平中心。
    
  • ratioY: float

    含义:ratioY 是一个浮点数,表示点击点相对于控件高度的比例位置。它的取值范围是 0 到 1。
    0 表示点击点位于控件的最顶侧边缘。
    1 表示点击点位于控件的最底侧侧边缘。
    0.5(默认值)表示点击点位于控件的水平中心。
    
  • simulateMove: bool

    含义: 这个布尔值参数决定了在执行点击动作时,鼠标指针移动到目标坐标点的方式。
    false:
        当设置为 false 时,鼠标指针会直接瞬间移动到指定的目标坐标点。
        用户将不会看到鼠标指针的移动轨迹,仿佛鼠标指针“瞬移”到了新位置。
        这种方式通常更快,但缺乏自然的交互感觉,因为真实的用户操作一般会有移动的过程。
    true:
        如果设置为 true,则鼠标指针会从当前坐标点开始,缓慢且平滑地移动到目标坐标点。
        用户能够看到鼠标指针的移动路径,模拟了更自然的人机交互过程。
        这种方式虽然可能稍微慢一些,但它提供了更加真实的用户体验,并且对于某些自动化测试场景来说,可以更好地模拟实际用户的操作行为。
    
  • 10. 使用 uiautomation 常见问题

    问题 1: 权限问题

    描述:在某些情况下,uiautomation 可能需要管理员权限才能正常工作,尤其是在枚举控件或获取控件信息时。

    解决方案

  • 管理员权限运行: 在 Windows 系统中,右键点击 Python 解释器或 IDE(如 PyCharm、VSCode),选择“以管理员身份运行”。

  • 打包exe时添加管理员权限

    # 使用命令打包对应的主程序,生成xxx.spec文件
    pyinstaller -F --uac-admin xxx.py
    # 使用以下命令完成打包
    pyinstaller xxx.spec
    
  • 问题 2: 控件不在可见区域内,无法直接点击

    描述:尝试对一个不在当前可见区域内的控件(如滚动窗口外的按钮)进行点击时,可能会失败,因为该控件没有被渲染到屏幕上。

    解决方案

  • 显示目标控件并点击: 尝试将目标控件显示在视图中,然后点击

    target_control = uia.HyperlinkControl(Name="获取帮助")
    if target_control.Exists():
        for _ in range(10):
            if not target_control.IsOffscreen:  # 判断是否在视图中
                target_control.Click()
                break
            target_control.SendKeys("{PageDown}")  # 通过PageDown按钮来滚动页面
    
  • 直接发送按钮: 如果该控件可以通过按键的方式打开, 例如"Enter"

    target_control = uia.HyperlinkControl(Name="获取帮助")
    if target_control.Exists():
    	target_control.SendKeys("{Enter}")
    
  • 使用 Invoke 模式:如果控件支持 InvokePattern,可以直接调用 Invoke() 方法而不必关心它的可见性。

    target_control = uia.HyperlinkControl(Name="获取帮助")
    if target_control.Exists():
        target_control.GetInvokePattern().Invoke()
    
  • 问题 3: 查找过程中抛异常LookupError: Find Control Timeout(10s)

    描述:当使用 uiautomation 库进行控件查找时遇到 LookupError: Find Control Timeout(10s) 错误,这意味着在默认的超时时间内(通常是10秒),库未能找到指定的控件。这个问题可能由多种因素引起,包括但不限于页面加载延迟、控件属性不准确或动态变化、应用程序响应速度慢等。

    解决方案

  • 增加判断机制: 通过Exists()方法判断控件是否存在,存在后再进行操作

    target_control = uia.HyperlinkControl(Name="获取帮助")
    if target_control.Exists():
        target_control.GetInvokePattern().Invoke()
    
  • 增强稳定性:捕获异常并添加重试机制来提高脚本的稳定性

    for _ in range(3):
        try:
            target_control = uia.HyperlinkControl(Name="获取帮助")
            if target_control.Exists(1):
                target_control.Click()
                break
        except Exception as e:
            print(e)
    
  • 问题 4: 浮层或模态对话框遮挡目标控件

    描述:有时其他元素(如浮动广告、提示框)会暂时覆盖住你需要操作的目标控件。

    解决方案

  • 关闭或移除障碍物:查找并关闭任何可能遮挡目标控件的弹出窗口或浮动层。

    modal_dialog = WindowControl(Name="Modal Dialog")
    if modal_dialog.Exists():
        close_button = modal_dialog.ButtonControl(Name="Close")
        if close_button.Exists():
            close_button.Click()
    
  • 调整窗口层级:确保目标窗口处于最顶层,避免被其他窗口遮挡。

    main_window = WindowControl(Name="Main Application Window")
    # 通过SetTopmost方法置顶窗口
    main_window.SetTopmost方法置顶窗口(True)
    
  • 11. UIAutomationInitializerInThread

    with uia.UIAutomationInitializerInThread(): 是 Python 中使用 uiautomation 库时的一种上下文管理器(context manager),用于初始化和清理 UI Automation 环境。这个库主要用于自动化 Windows GUI 测试或与 Windows 应用程序进行交互。

    作用

    1. 线程安全初始化UIAutomationInitializerInThread 确保在多线程环境中正确初始化 COM (Component Object Model) 库,特别是为了支持 UI Automation。这是因为 UI Automation API 需要一个特定的 COM 线程模型来工作,通常是在 STA (Single-Threaded Apartment) 模式下。
    2. 资源管理:通过上下文管理器的方式,它确保了即使发生异常,也能正确地释放分配给 UI Automation 的资源。当代码块执行完毕或者遇到异常时,__exit__ 方法会被调用,从而自动清理并终止 COM 初始化。
    3. 简化代码:这种方式使得开发者不需要手动管理 COM 的初始化和清理,减少了代码复杂度,并且降低了出错的可能性。

    使用示例

    import uiautomation as uia
    
    # 正确使用上下文管理器来确保线程安全的初始化和清理
    with uia.UIAutomationInitializerInThread():
        # 在这里放置所有需要使用 UIAutomation 的代码
        window = uia.WindowControl(searchDepth=1, Name='Your Application Window')
        window.SetActive()
        button = window.ButtonControl(Name='Button Name')
        button.Click()
    
    # 当退出 with 语句块后,COM 环境会自动被清理
    

    注意事项

  • 避免嵌套:尽量不要在一个已经处于 UIAutomationInitializerInThread 上下文中的线程再次进入另一个 UIAutomationInitializerInThread 上下文,因为这可能会导致 COM 初始化问题。
  • 单线程模式:尽管名字中有“Thread”,但最好保证每个线程中只有一个 UIAutomationInitializerInThread 实例,以维持 COM 的正确初始化状态。
  • 性能考虑:由于每次进入上下文都会初始化 COM 环境,如果频繁进出这个上下文,可能会影响性能。对于长时间运行的应用程序或脚本,可以考虑仅在必要的时候才使用此上下文管理器。
  • 总之,with uia.UIAutomationInitializerInThread(): 提供了一种方便、安全的方法来处理 UI Automation 的初始化和资源管理,特别是在多线程环境下。它有助于确保应用程序稳定性和减少开发者的负担。

    12. uiautomation封装方法

    1. 获取所有顶级窗口
    import uiautomation as uia
    
    
    def get_all_windows():
        """
        获取所有顶级窗口。
    
        Returns:
            list: 包含所有顶层窗口控件对象的列表。
        """
        # 使用uiautomation库获取根控件(桌面)
        root = uia.GetRootControl()
        # 查找所有具有名称属性的顶级窗口
        return [window for window in root.GetChildren() if window.Name]
    
    2. 通过名称列表查找多个窗口
    def find_windows_by_name(names: (list, str), all_windows=None, identical: bool = False):
        """
        通过名称列表查找多个窗口
    
        Args:
            names (list of str): 窗口的名称或标题列表。
            all_windows (list, 可选): 根控件下的所有控件列表,默认为None将调用get_all_windows获取。
            identical (bool): 是否需要完全匹配名称,默认False表示部分匹配。
    
        Returns:
            list: 匹配条件的窗口控件列表。
        """
        if all_windows is None:
            all_windows = get_all_windows()
        names = names if isinstance(names, list) else [names]
    
        def match_func(window):
            window_name_lower = window.Name.lower() if window.Name else ''
            for name in names:
                name_lower = name.lower()
                if identical and window.Name == name:
                    return True
                elif not identical and name_lower in window_name_lower:
                    return True
            return False
    
        return [window for window in all_windows if match_func(window)]
    
    3. 等待指定名称的窗口出现。
    def wait_windows_by_name(names: (list, str), timeout: float = 10, poll_interval: float = 0.5, identical: bool = False):
        """
        等待指定名称的窗口出现。
    
        Args:
            names (list of str): 窗口的名称或标题列表。
            timeout (float): 等待窗口出现的最大秒数,默认为10秒。
            poll_interval (float): 每次检查之间的间隔秒数,默认为0.5秒。
            identical (bool): 是否需要完全匹配名称,默认False表示部分匹配。
    
        Returns:
            list: 匹配条件的窗口控件列表。
    
        """
        end_time = time.time() + timeout
    
        while time.time() < end_time:
            try:
                # 尝试查找窗口
                windows = find_windows_by_name(names, identical=identical)
                if windows:
                    return windows
                # 如果没有找到,等待一段时间再重试
                time.sleep(poll_interval)
            except Exception as e:
                logger.error(e)
        # 超时后处理
        return []
    

    作者:Midway-Z

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python uiautomation模块实战指南

    发表回复