Приложение Windows, автоматизирующее использование pywinauto, не обнаруживает элементы внутри TreeView, несмотря на то, что элементы имеют собственные характеристики.

метод древовидного представленияДревовидная структура spy++ Приложение, которое я автоматизирую, представляет собой серверное приложение с поддержкой win32 и использует inspect.exe для обнаружения элементов Ниже приведен мой код пытаюсь нажать на элемент чека, при выполнении получаю ошибку

code:скриншот древовидной структуры в inspect.exe, когда изображение приложения находится в фоновом режиме

app = Application(backend="win32").connect(process=5468)
app.windows()
dlg = app['TFMenuG.UnicodeClass']
handle = dlg.child_window(control_id='UIA_ButtonControlTypeId (0xC350)').draw_outline()

ошибка:

Traceback (most recent call last):
  File "c:\..\pythonDemo\notepad.py", line 62, in <module>
    handle = dlg.child_window(control_id='UIA_ButtonControlTypeId (0xC350)').draw_outline()
  File "C:\..\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pywinauto\application.py", line 379, in __getattribute__
    ctrls = self.__resolve_control(self.criteria)
  File "C:\..\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pywinauto\application.py", line 261, in __resolve_control
    raise e.original_exception
  File "C:\..\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pywinauto\timings.py", line 436, in wait_until_passes
    func_val = func(*args, **kwargs)
  File "C:\..\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pywinauto\application.py", line 222, in __get_ctrl
    ctrl = self.backend.generic_wrapper_class(findwindows.find_element(**ctrl_criteria))
  File "C:\..\AppData\Local\Programs\Python\Python39-32\lib\site-packages\pywinauto\findwindows.py", line 87, in find_element
    raise ElementNotFoundError(kwargs)
pywinauto.findwindows.ElementNotFoundError: {'control_id': 'UIA_ButtonControlTypeId (0xC350)', 'top_level_only': False, 'parent': <win32_element_info.HwndElementInfo - '', TFMenuG.UnicodeClass, 196780>, 'backend': 'win32'}

Помогите, пожалуйста, определить элементы. Я сомневаюсь, что элементы не распознаются из-за бэкенда win32.


person mani    schedule 14.05.2021    source источник


Ответы (1)


Во-первых, если вы используете Inspect.exe, вы должны использовать Application(backend="uia"). Если вы хотите проверить совместимость приложения со старым бэкендом win32, вам понадобится Spy++, который входит в состав Visual Studio.

Второй control_id — это целочисленный идентификатор от Spy++, и он может быть несовместимым от запуска к запуску. Я бы рекомендовал печатать тексты окон верхнего уровня с помощью print([w.window_text() for w in app.windows()]) и использовать необходимый текст для идентификации окон верхнего уровня и дампа дочерних идентификаторов:

app.window(title="Main Window Title").dump_tree() # or use title_re for regular expression
app.window(title="Main Window Title").child_window(title="Sales Receipts", control_type="TreeItem").draw_outline().click_input()
# or get .wrapper_object() and discover all available methods,
# wrapper methods can be chained as above

P.S. Если Inspect.exe не показывает свойство NativeWindowHandle, это означает, что элемент не виден для бэкенда win32.


РЕДАКТИРОВАТЬ1:

Попробуйте этот код для Win32 TreeView, который не определяется автоматически как TreeViewWrapper:

from pywinauto import Application
from pywinauto.controls.common_controls import TreeViewWrapper

app = Application(backend="win32").connect(class_name="TFMenuG.UnicodeClass")
dlg = app['TFMenuG.UnicodeClass']
handle = dlg.child_window(class_name='THTreeView.UnicodeClass').wrapper_object().handle
tree_view = TreeViewWrapper(handle)
print(dir(tree_view)) # list all available methods

tree_view.get_item("Sales Receipts").expand()
tree_view.get_item(r"Sales Receipts\Reports").click(where="text")

Когда вы увидите все доступные методы, попробуйте задокументированные методы для Win32 TreeView: https://pywinauto.readthedocs.io/en/latest/code/pywinauto.controls.common_controls.html#pywinauto.controls.common_controls.TreeViewWrapper Обратите внимание, что объект _treeview_element возвращается get_item(...) представляет конкретный элемент без дескриптора окна, но его можно использовать.

person Vasily Ryabov    schedule 15.05.2021
comment
Спасибо @VasilyRyabov 1) бэкэнд «Приложение (бэкенд = uia)» не идентифицирует приложение. Когда я пытаюсь проверить с помощью spy++ и использовать код 'app = Application(backend=win32).connect(class_name=TFMenuG.UnicodeClass) app.windows() dlg = app['TFMenuG.UnicodeClass'] handle = dlg.child_window(class_name ='THTreeView.UnicodeClass').wrapper_object()' это plrints 'hwndwrapper.HwndWrapper - '', THTreeView.UnicodeClass' - person mani; 17.05.2021
comment
Хотя, если я попытаюсь щелкнуть dlg.child_window(class_name='THTreeView.UnicodeClass').click(), он просто щелкнет первый элемент в дереве, который является скриптом продаж, он не показывает мне другое свойство, чтобы щелкнуть дочерние элементы дерева. Прикрепляю скриншот древовидного структуратора в spy++ к вопросу. Есть ли способ щелкнуть другие элементы дерева. Спасибо - person mani; 17.05.2021
comment
Я могу предложить способ явно обернуть элемент win32 с помощью TreeViewWrapper. Смотрите обновленный ответ. Хотя гарантии нет. Пожалуйста, дайте мне знать, если это работает. Я могу добавить еще одно регулярное выражение в список автоопределения по class_name. - person Vasily Ryabov; 17.05.2021
comment
Я попытался print (tree_view.print_items()), который напечатал всю древовидную структуру каждого древовидного представления, имея все имена элементов. Также, когда я пытаюсь сделать tree_view.select(\Sales квитанции\Sales)`, он выделяет Sales в разделе Sales квитанции. Но когда я пытаюсь сделать tree_view.get_item("\Sales Receipts").expand() tree_view.get_item(r"\Sales receipts\Sales").click(where="Sales"), я получаю сообщение об ошибке `raise RuntimeError(Область ('{}') не найдена для этого элемента представления дерева. Формат(где)) RuntimeError: Область ("Продажи") не найдена для этого элемента представления дерева` . Не уверен, что мне не хватает. Пожалуйста помоги. Спасибо - - person mani; 18.05.2021
comment
Также добавлен снимок экрана в вопрос о методах, напечатанных в виде дерева, который показывает метод щелчка. - person mani; 18.05.2021
comment
Я обнаружил, что древовидное представление расширяется только тогда, когда я нажимаю знак «+» (чтобы развернуть и «-», чтобы свернуть) перед текстом в древовидной структуре, Spy++ не идентифицирует эти знаки. ИЛИ когда я вручную дважды щелкаю по тексту. tree_view.get_item("\Sales receipts\Sales").double_click()не работает, выдает ошибку AttributeError: '_treeview_element' object has no attribute 'double_click' - person mani; 19.05.2021
comment
Решил эту проблему, выбрав древовидную структуру с помощью tree_view.get_item("\Sales receipts\Sales").get_child("Enter receipt").select(). Закрытие этой темы - person mani; 19.05.2021
comment
tree_view.get_item("\Sales receipts\Sales\Enter receipt").select() тоже должно работать. Параметр where может иметь только предустановленные значения: текст, галочку, иконку, которые являются разными частями одной позиции. - person Vasily Ryabov; 20.05.2021