我试图使用pywinauto& amp尝试自动化一个简单的应用程序Python 3.6。该应用程序有一个Windows" Open"像这样的对话框,我想点击"取消"按钮:
我使用SWAPY来获取按钮的class_name和control_id属性。
现在的问题是,当我用这些参数调用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方法。
答案 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中描述。请阅读整个指南。你会发现很多有用的高级东西。如果某些事情仍然不明确,我可以为一些角落案件提供建议。