pywinauto:遍历窗口中的所有控件

时间:2018-08-30 11:39:37

标签: python pywinauto

我正在尝试编写通用的测试脚本以查找新软件版本中的错误。我的想法是遍历窗口中的控件并与每个控件进行交互,记录所引起的任何错误,并在软件崩溃时重新启动。

我正在寻找一种动态查找控件标识符的方法,有点像print_control_identifiers(),但输出是可以迭代的列表或类似结构。

在关于控件标识符的GitHub question上提到:

  

可以通过使用.children()(仅用于直接子级)和.descendants() (整个子树作为纯列表)来遍历层次结构

我以为我可以遍历Application对象的descendants()列表并为每个对象调用相对的交互方法,但是我无法弄清楚如何获得此列表。我以为我可以做这样的事情,但是我没有成功:

def test(application):
    for child in application.descendants():
        #interact with child control

software = Application(backend='uia').start(cmd_line=FILE_PATH)
test(software)

AttributeError:找不到GUI元素(包装器)或包装器方法“后裔”(打字错误)


编辑


我诉诸于the code,发现了print_control_identifiers方法:

class Application(object):

    def print_control_identifiers(self, depth=None, filename=None):
        """
        Prints the 'identifiers'
        Prints identifiers for the control and for its descendants to
        a depth of **depth** (the whole subtree if **None**).
        .. note:: The identifiers printed by this method have been made
               unique. So if you have 2 edit boxes, they won't both have "Edit"
               listed in their identifiers. In fact the first one can be
               referred to as "Edit", "Edit0", "Edit1" and the 2nd should be
               referred to as "Edit2".
        """
        if depth is None:
            depth = sys.maxsize
        # Wrap this control
        this_ctrl = self.__resolve_control(self.criteria)[-1]

        # Create a list of this control and all its descendants
        all_ctrls = [this_ctrl, ] + this_ctrl.descendants()

        # Create a list of all visible text controls
        txt_ctrls = [ctrl for ctrl in all_ctrls if ctrl.can_be_label and ctrl.is_visible() and ctrl.window_text()]

        # Build a dictionary of disambiguated list of control names
        name_ctrl_id_map = findbestmatch.UniqueDict()
        for index, ctrl in enumerate(all_ctrls):
            ctrl_names = findbestmatch.get_control_names(ctrl, all_ctrls, txt_ctrls)
            for name in ctrl_names:
                name_ctrl_id_map[name] = index

        # Swap it around so that we are mapped off the control indices
        ctrl_id_name_map = {}
        for name, index in name_ctrl_id_map.items():
            ctrl_id_name_map.setdefault(index, []).append(name)

这表明.descendants()不是Application类的方法,而是属于控件。看来我错了。是否可以创建我自己的print_control-identifiers()版本,该版本返回可以迭代的控制对象列表?

1 个答案:

答案 0 :(得分:2)

列出顶级窗口的正确方法是;WITH SumValues AS ( SELECT Application_ID ,SUM(Amount) As SumAmount FROM TableName GROUP BY Application_ID ) SELECT Application_ID FROM SumValues WHERE SumAmount >= 40 。然后,您可以为每个列出的窗口调用application.windows()。在大多数情况下,应用程序只有一个顶层窗口。特别是对于.descendants(),甚至新的对话框也是主窗口的子级(对于backend="uia",每个对话框都是顶级窗口)。