You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PyWinAuto识别DataGrid中勾选图标问题求助

问题描述

我用PyWinAuto从文件编辑器取数,代码如下:

app = Application(backend='uia').connect(title='AppTitle', timeout=2)
dlg = app.top_window()
list_child = dlg.child_window(auto_id="dgFileEditor", control_type="DataGrid").children()

for item in list_child:
    for cell in item.children():
        for smaller_cell in cell.children():
            element_info = smaller_cell.window_text()
            print(element_info)

现在需要验证带勾选图标的数据行,但Inspect.exe找不到该图标,鼠标悬停时它被识别为无父子节点的DataGridCell。以下是Inspect.exe输出:

How found:  Mouse move (3128,628)
    hwnd=0x0000000000230A20 32bit class="HwndWrapper[SmartTrans.exe;;9f06b796-7f7e-4981-92a6-680f950e21e7]" style=0x17CF0000 ex=0x4Name:    "Item: SmartTrans.Model.SegmentElement, Column Display Index: 4"
ControlType:    UIA_CustomControlTypeId (0xC369)
LocalizedControlType:   "data grid cell"
BoundingRectangle:  {l:3101 t:601 r:3139 b:646}
IsEnabled:  true
IsOffscreen:    false
IsKeyboardFocusable:    true
HasKeyboardFocus:   false
AcceleratorKey: ""
AccessKey:  ""
ProcessId:  9748
RuntimeId:  [7.2614.20C235B]
AutomationId:   ""
FrameworkId:    "WPF"
ClassName:  "DataGridCell"
IsControlElement:   true
IsContentElement:   true
ProviderDescription:    "[pid:9748,providerId:0x0 Main(parent link):Unidentified Provider (managed:MS.Internal.Automation.ElementProxy, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)]"
LiveSettingProperty:    Off (0)
IsPassword: false
ItemStatus: ""
ItemType:   ""
IsRequiredForForm:  false
HelpText:   ""
ClickablePoint: {x:3120 y:623}
Orientation:    0
IsDialog:   false
HeadingLevel:   HeadingLevel_None (0x138B2)
GridItem.Column:    4
GridItem.ColumnSpan:    1
GridItem.ContainingGrid:    "" datagrid
GridItem.Row:   67
GridItem.RowSpan:   1
LegacyIAccessible.ChildId:  0
LegacyIAccessible.DefaultAction:    "Press"
LegacyIAccessible.Description:  ""
LegacyIAccessible.Help: ""
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: "Item: SmartTrans.Model.SegmentElement, Column Display Index: 4"
LegacyIAccessible.Role: push button (0x2B)
LegacyIAccessible.State:    focusable (0x100000)
LegacyIAccessible.Value:    ""
Value.IsReadOnly:   false
Value.Value:    ""
Table.ItemColumnHeaderItems:    
Table.ItemRowHeaderItems:   
IsAnnotationPatternAvailable:   false
IsDragPatternAvailable: false
IsDockPatternAvailable: false
IsDropTargetPatternAvailable:   false
IsExpandCollapsePatternAvailable:   false
IsGridItemPatternAvailable: true
IsGridPatternAvailable: false
IsInvokePatternAvailable:   true
IsItemContainerPatternAvailable:    false
IsLegacyIAccessiblePatternAvailable:    true
IsMultipleViewPatternAvailable: false
IsObjectModelPatternAvailable:  false
IsRangeValuePatternAvailable:   false
IsScrollItemPatternAvailable:   true
IsScrollPatternAvailable:   false
IsSelectionItemPatternAvailable:    false
IsSelectionPatternAvailable:    false
IsSpreadsheetItemPatternAvailable:  false
IsSpreadsheetPatternAvailable:  false
IsStylesPatternAvailable:   false
IsSynchronizedInputPatternAvailable:    false
IsTableItemPatternAvailable:    true
IsTablePatternAvailable:    false
IsTextChildPatternAvailable:    false
IsTextEditPatternAvailable: false
IsTextPatternAvailable: false
IsTextPattern2Available:    false
IsTogglePatternAvailable:   false
IsTransformPatternAvailable:    false
IsTransform2PatternAvailable:   false
IsValuePatternAvailable:    true
IsVirtualizedItemPatternAvailable:  false
IsWindowPatternAvailable:   false
IsCustomNavigationPatternAvailable: false
IsSelectionPattern2Available:   false
FirstChild: [null]
LastChild:  [null]
Next:   "Item: SmartTrans.Model.SegmentElement, Column Display Index: 5" data grid cell
Previous:   "Item: SmartTrans.Model.SegmentElement, Column Display Index: 3" data grid cell
Other Props:    Object has no additional properties
Children:   Container has no children
Ancestors:  "SmartTrans.Model.SegmentElement" dataitem
    "" datagrid
    "SmartTrans" window
    "Desktop 1" pane
    [ No Parent ]

试过截图和获取提示文本都没用,求解决方法。

解决方法

针对WPF自定义绘制的勾选图标(无独立自动化节点),可尝试以下方案:

  • 获取单元格全量属性:不要仅调用window_text(),用get_properties()输出所有属性,排查隐藏状态字段:
for item in list_child:
    for cell in item.children():
        # 定位到目标列(Column=4)的单元格
        if cell.get_properties().get('GridItem.Column') == 4:
            props = cell.get_properties()
            print("单元格全量属性:", props)
            # 重点检查Value、LegacyIAccessible相关字段
            print("Value字段值:", props.get('Value.Value'))
            print("LegacyIAccessible状态:", props.get('LegacyIAccessible.State'))
  • 关联数据行的DataItem:单元格父节点为SmartTrans.Model.SegmentElement dataitem,尝试从行节点读取业务数据中的勾选状态:
for item in list_child:
    # item即为dataitem行节点
    row_props = item.get_properties()
    # 检查ItemStatus等可能携带状态的字段
    print("行ItemStatus:", row_props.get('ItemStatus'))
    
    for cell in item.children():
        if cell.get_properties().get('GridItem.Column') == 4:
            # 尝试调用InvokePattern模拟点击,观察属性变化
            try:
                cell.invoke()
                new_props = cell.get_properties()
                print("点击后属性变化:", new_props)
            except Exception as e:
                print("Invoke操作失败:", e)
  • 像素级验证(备选):若上述方法无效,截取单元格区域图像,与预存的勾选/未勾选图标做像素比对:
import pyautogui
from PIL import Image

for item in list_child:
    for cell in item.children():
        props = cell.get_properties()
        if props.get('GridItem.Column') == 4:
            rect = props.get('BoundingRectangle')
            # 截取单元格区域
            screenshot = pyautogui.screenshot(region=(rect['l'], rect['t'], rect['r']-rect['l'], rect['b']-rect['t']))
            # 加载预存的标准勾选图标
            standard_check = Image.open("check_icon.png")
            # 计算像素差异率
            diff_count = 0
            total_pixels = screenshot.width * screenshot.height
            for x in range(screenshot.width):
                for y in range(screenshot.height):
                    if screenshot.getpixel((x,y)) != standard_check.getpixel((x,y)):
                        diff_count +=1
            # 差异率低于10%视为已勾选
            if diff_count / total_pixels < 0.1:
                print("该行已勾选")
            else:
                print("该行未勾选")
  • 尝试获取Toggle状态:尽管Inspect显示IsTogglePatternAvailable为false,仍可尝试调用get_toggle_state()排查兼容问题:
for item in list_child:
    for cell in item.children():
        if cell.get_properties().get('GridItem.Column') == 4:
            try:
                toggle_state = cell.get_toggle_state()
                if toggle_state == 1: # ToggleState.On
                    print("已勾选")
                else:
                    print("未勾选")
            except Exception as e:
                print("无法获取Toggle状态:", e)

内容的提问来源于stack exchange,提问作者Quang Huy Vũ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:24:52