Я использую последний код 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]
Но, в конце концов, ничего из этого не работало согласованно, иногда это работает, но когда я получаю этот дополнительный щелчок на элементе подменю над ожидаемым, он всегда завершается ошибкой, потому что заставляет исчезать правильное меню.