使用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.SegmentElementdataitem,尝试从行节点读取业务数据中的勾选状态:
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ũ
相关产品推荐
相关产品推荐

