pywinauto find_elements()返回ElementNotFoundError

时间:2017-05-09 13:42:08

标签: python pywinauto

我试图使用pywinauto& amp尝试自动化一个简单的应用程序Python 3.6。该应用程序有一个Windows" Open"像这样的对话框,我想点击"取消"按钮: enter image description here

我使用SWAPY来获取按钮的class_name和control_id属性。 enter image description here

现在的问题是,当我用这些参数调用find_element()方法时,它会引发一个ElementNotFoundError。这是我的代码:

cancel_button = pywinauto.findwindows.find_element(class_name="button", control_id=2)

我已经尝试了(class_name="button", control_id="2")(class_name="Button", control_id=2),但他们都犯了同样的错误。我尝试在此对话框中找到的任何其他元素也会出现同样的问题。

那么如何使用从SWAPY读取的属性?我没有找到官方的pywinauto文档非常有用。它没有清楚地解释很多事情。

编辑:我决定不使用find_elements方法,而是使用find_windows()来获取“打开”对话框的句柄。

w_open_handle = pywinauto.findwindows.find_windows(title=u'Open', class_name='#32770')[0]

然后我使用这个句柄获取一个WindowSpecification对象:

w_open = app.window_(handle=w_open_handle)
然后我打电话给:

w_open['Cancel'].click()

这是有效的。现在我想在"文件名中输入文件名:"编辑框并单击“打开”按钮以打开该文件。所以我这样做:

w_open['File name:'].type_keys("abc.txt")

这很有效。我使用print_control_identifiers()打印出控件标识符,并获得了Open按钮的名称。所以使用draw_outline()我在它外面绘制一个边界,它显示正确的按钮。

w_open['SplitButton6'].draw_outline()

但是在' SplitButton6'上调用.click()方法。抛出 WindowSpecification类没有'点击'方法错误。知道是什么引起了这个吗?该错误似乎具有误导性,因为WindowSpec类确实有.click方法。

1 个答案:

答案 0 :(得分:1)

正确答案是您错过了top_level_only=False(默认为True,因为更高级别的API会至少调用它两次)。然后,您可能有2个符合此条件的控件(可能来自不同的应用程序)。 find_element是一个低级功能。我不建议直接使用它(代码太长,在更高级别的API上考虑了很多陷阱)。

>>> pywinauto.findwindows.find_element(class_name="Button", control_id=2, top_level_only=False)
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "...\pywinauto\findwindows.py", line 98, in find_element
    raise exception
ElementAmbiguousError: There are 2 elements that match the criteria {'class_name': 'Button', 'control_id': 2, 'top_level_only': False}

>>> pywinauto.findwindows.find_element(class_name="Button", title='Cancel', top_level_only=False)
<win32_element_info.HwndElementInfo - 'Cancel', Button, 395554>

使用更高级别的API(指南中描述的Application对象和WindowSpecification),您不应该每次都将进程ID,后端名称和其他内容传递给find_element

P.S。在我看来,SWAPY可以得到显着改善,但去年并没有保持。我希望将来能够通过更小的代码库和MS UI Automation支持重新编写它。但目前全自动脚本生成器的优先级更高。

编辑:

此按钮w_open['SplitButton6'].draw_outline()可以被检测为常规HwndWrapper对象,而不是ButtonWrapper。您可以使用以下方法进行检查:

w_open['SplitButton6'].wrapper_object()

这就是“入门指南”中的内容(您说过您已经阅读过)。

幸运的是,您可以使用方法.click_input()进行任何控制:

w_open['SplitButton6'].click_input()

我可以说更多:WindowSpecification没有click方法。它是动态实例化的ButtonWrapper方法。例如,这些语句的工作方式相同(但Python可以隐藏.wrapper_object()调用):

w_open['SplitButton6'].wrapper_object().click_input()
w_open['SplitButton6'].click_input()

这再次在Getting Started Guide中描述。请阅读整个指南。你会发现很多有用的高级东西。如果某些事情仍然不明确,我可以为一些角落案件提供建议。