我正在尝试使用pywinauto &Python3.6来自动化一个简单的应用程序。这个应用程序有一个像这样的Windows“打开”对话框,我想点击“取消”按钮:
我使用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()
而且这个很管用。现在,我想在“文件名:”编辑框中输入一个文件名,然后单击Open按钮来打开该文件。所以我就这么做:
w_open['File name:'].type_keys("abc.txt")
这个很管用。我使用print_control_identifiers()打印出了控制标识符,并获得了Open按钮的名称。因此,使用draw_outline(),我在它外面画了一个边界,它显示了正确的按钮。
w_open['SplitButton6'].draw_outline()
但是,在'SplitButton6‘上调用SplitButton6()方法会抛出一个WindowSpecification类,没有“单击”方法错误。知道是什么导致的吗?由于WindowSpec类确实有一个.click方法,该错误似乎具有误导性。
发布于 2017-05-10 07:44:31
正确的答案是您错过了top_level_only=False
(默认情况下是True
,因为更高级别的API至少两次调用它)。然后可能有两个与此标准相匹配的控件(可能来自不同的应用程序)。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
。
在我看来,SWAPY可以得到很大的改善,但去年没有得到维护。我希望在将来用更小的代码库和MS自动化支持来重写它。但目前,全自动脚本生成器是一个更高的优先级。
编辑:
可以将此按钮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()
同样,这在入门指南中也有描述。请阅读整本指南。你会发现很多有用的高层次的东西。如果还有什么不清楚的话,我可以为一些角落的案子提供建议。
https://stackoverflow.com/questions/43871504
复制相似问题