Search code examples
pythonpython-3.xpywinauto

Using pywinauto to read a value within a window and use in a function


I am building an automation script with python using pywinauto, and I am stumped on this part. So far I'm able to start the app, or connect to it. I've toggled through the windows in the interface, and now it needs to somehow read the value and compare to the contents of a .csv file and continue with more functions. The app has multiple windows and one of them uses a spreadsheet type interface. There is not a find/replace feature, or else I could just use that.

Now comes the challenge. It needs to "see" the string within a cell and I can easily do this using AccExplorer or Inspect.exe. This is the cell structure in the app, with the selected item "CAM 2". Cell example from the app

AccExplorer window showing results of the cell And this is the result provided by AccExplorer. The red circle indicates the "value" I wish to find, and use for comparison. (I have found that searching for this topic on "value" results in answers that are too vague, rather than my literal need to find the value of "value" in this case.)

By using this code in my script passing in the class of the window provided by the AccExpolorer tool (red arrow for the class)

edit = wdow['WindowsForms10.Window.8.app.0.378734a'] 
props = edit.GetProperties() 
print(props)

It does not return the "Value" field or its property in this case should be "Cam 2"

{'class_name': 'WindowsForms10.Window.8.app.0.378734a',
 'friendly_class_name': 'WindowsForms10.Window.8.app.0.378734a', 
'texts': [''], 'control_id': 1639674, 'rectangle': <RECT L0, T47, R1366, B746>, 
'is_visible': True, 'is_enabled': True, 'control_count': 76, 'style': 1442906112, 
'exstyle': 65536, 'user_data': 0, 'context_help_id': 0, 
'fonts': [<LOGFONTW 'MS Shell Dlg' -11>], 
'client_rects': [<RECT L0, T0, R1366, B699>], 
'is_unicode': True, 'menu_items': []}

I am rather new to python (and programming in general) but I have been doing quite well at grasping all of this. I am aware of the backend, which I have not had luck with using UIA, and it seems to be working so far with the default. Also, I've tried using SWAPY and it displays a lot of class names as duplicates, and does not show this level of cell values directly.

The main question is what would I be doing wrong to get this data, or is it even possible to get it this way? I am open to any suggestions or even using other libraries. I just figured this would be the cleanest and easiest. Thanks!


Solution

  • For begin read getting started guide and see some examples

    You choose not better way to get cell of DataGridView, try to use UIA backend for that

    from pywinauto import Desktop
    
    dlg = Desktop(backend="uia")["YourApplicationName"]
    
    # use that function for found your DataGridView
    #dlg.print_control_identifiers()
    datagrid = dlg.DataGridView
    
    # use for found some particular cell
    #datagrid.print_control_identifiers()
    
    # in my case it was DataItem
    cell = dlg.DataGridView.DataItem
    
    # way to get item value
    print(cell.legacy_properties()['Value'])
    

    You also can use indexes for choose from a lot of same cells, like "DataItem0" or get all cells using lambda:

    cells = [child for child in datagrid.descendants() if child.element_info.control_type == "DataItem"]
    for cell in cells:
        print(cell.legacy_properties()['Value'])