Не удается получить доступ к элементу подменю с бэкэндом UIA - PullRequest
1 голос
/ 05 июля 2019

Я использую последний код Pywinauto от GitHub на 2019/07/04.

Я пытаюсь получить доступ к меню / подменю приложения на основе Eclipse. Код, который я использую для этого:

mainwinobj.menu_select("Project->My first menu->my second menu(specific)")

К сожалению, это вызывает исключение:

Traceback (most recent call last):
  File <MYPATH>\pywinauto\controls\uia_controls.py", line 1073, in item_by_path
    menu = next_level_menu(menu, menu_items[i], items_cnt == i + 1)
  File "<MYPATH>\pywinauto\controls\uia_controls.py", line 1053, in next_level_menu
    return self._sub_item_by_text(parent_menu, item_name, exact, is_last)
  File "<MYPATH>\pywinauto\controls\uia_controls.py", line 1017, in _sub_item_by_text
    self._activate(sub_item, is_last)
  File "<MYPATH>\pywinauto\controls\uia_controls.py", line 984, in _activate
    if not item.is_active():
AttributeError: 'NoneType' object has no attribute 'is_active'

Тем не менее, я вижу, что он правильно нажал на My first menu, но не на втором.

Я также получаю противоречивое поведение , иногда я вижу, что он ошибочно нажимает на подменю, расположенное графически над My first menu после правильного нажатия на My first menu, в результате чего правильное подменю исчезает из экран. Это не меняет того, что исключение происходит, но оно влияет на обходные пути, которые я попробовал, как описано ниже.

корень, вызывающий проблему

Я быстро смог понять причину проблемы: в _sub_item_by_text, строка

items = menu.items()

возвращает пустой список, и поэтому sub_item остается None.

проверенные решения

Я пробовал много разных вещей вокруг основного решения, которые иногда приводили к правильному поведению, но оно никогда не было последовательным. По сути, я заставляю искать в окнах, чтобы попытаться найти Меню:

        if not menu.items():
            print("waiting for menu " + menu.window_text())
            time.sleep(1)
            menus = menu.top_level_parent().children(control_type="Menu", title=menu.window_text())
            print(menus)
            menu = menus[0]

или другое решение, например:

        if not menu.items():
            print("waiting for menu " + menu.window_text())
            self._activate(menu, False)
            timings.wait_until(
                timings.Timings.window_find_timeout,
                timings.Timings.window_find_retry,
                lambda: len(self.top_level_parent().descendants(control_type="Menu", title=menu.window_text())) > 0)
            menus = menu.top_level_parent().children(control_type="Menu", title=menu.window_text())
            print(menus)
            menu = menus[0]

или я снял активацию:

        if not menu.items():
            print("waiting for menu " + menu.window_text())
            timings.wait_until(
                timings.Timings.window_find_timeout,
                timings.Timings.window_find_retry,
                lambda: len(self.top_level_parent().descendants(control_type="Menu", title=menu.window_text())) > 0)
            menus = menu.top_level_parent().children(control_type="Menu", title=menu.window_text())
            print(menus)
            menu = menus[0]

Но, в конце концов, ничего из этого не работало согласованно, иногда это работает, но когда я получаю этот дополнительный щелчок на элементе подменю над ожидаемым, он всегда завершается ошибкой, потому что заставляет исчезать правильное меню.

...