5

如何使用findObject()waitForObject()不使用对象映射通过 id 或 objectName 获取 QML 元素?甚至可能吗?

考虑:

Item {
    id: page
    objectName: "pageObject"

    Text {
        id: foobar
        objectName: "lorem"
        text: "ipsum"
    }
}

我想在测试脚本中访问 foobar 的文本,例如:

obj = findObject("foobar")
if obj.text == "ipsum":
    test.passes("all good")
else:
    test.fail("uh oh")

我也试过:

obj = findObject("lorem")
obj = findObject("{name='lorem'}")
obj = findObject("{name='lorem' type='Text'}")
obj = findObject("{objectName='lorem'}")
obj = findObject("{objectName='lorem' type='Text'}")
4

3 回答 3

1

最终我通过在对象映射中只使用根级别对象解决了这个问题。所有其他对象都使用下面的函数在代码中迭代。

import sys
import time

# Definitions
ROOT_SYMBOLIC_OBJECT = ":_KMainView"

# Object finding functions
def findSymbolic(symbolicName):
    # Note: give Squish symbolic name like ":Foobar"
    try:
        obj = findObject(symbolicName)
    except LookupError:
        sys.exc_clear()
        test.log("FAIL: Root object not found: " + symbolicName)
        sys.exit()

    return obj

def findRoot():
    return findSymbolic(ROOT_SYMBOLIC_OBJECT)

def findFlat(fromElement, findId, occurence, stopOnFail, verbose):
    start = time.time()
    result = None
    found = 0

    if fromElement and hasattr(fromElement, 'children'):
        children = object.children(fromElement)
        for child in children:
            if hasattr(child, 'id') and child.id == findId:
                found += 1
                if found == occurence:
                    result = child
                    break

    if result == None and stopOnFail:
        test.log("FAIL: findFlat: " + findId + " not found")
        sys.exit()

    if verbose:
        printElapsed("findFlat", findId, start)

    return result

def findRecursive(fromElement, findId, occurence):
    return findRecursiveWithOptions(fromElement, findId, occurence, True, False, True)

def findRecursiveWithOptions(fromElement, findId, occurence, stopOnFail, verbose, skipUnnamed):
    start = time.time()
    found = 0
    depth = -1

    obj, found, depth = objIter(fromElement, findId, occurence, verbose, skipUnnamed, found, depth)

    if found == occurence:
        printElapsed("findRecursive ok", findId, start)
        return obj

    printElapsed("findRecursive not found", findId, start)
    if stopOnFail:
        test.log("FAIL: findRecursive:" + findId + " not found.")
        sys.exit()

    return None 

def objIter(fromElement, findId, occurence, verbose, skipUnnamed, found, depth):
    depth += 1

    if verbose:
        printObjIter(fromElement, depth)

    children = object.children(fromElement)
    for child in children:
        if hasattr(child, 'id'):
            if child.id == findId:
                found += 1
                if found == occurence:
                    return child, found, depth
        elif skipUnnamed:
            continue

        obj, found, depth = objIter(child, findId, occurence, verbose, skipUnnamed, found, depth)
        depth = depth - 1
        if found == occurence: 
            return obj, found, depth

    return None, found, depth

def findRecursiveList(fromElement, findId):
    return findRecursiveListWithOptions(fromElement, findId, True, False, True)

def findRecursiveListWithOptions(fromElement, findId, stopOnFail, verbose, skipUnnamed):
    start = time.time()
    objList = []
    depth = -1

    objList, depth = objListIter(fromElement, findId, verbose, skipUnnamed, objList, depth)

    printElapsed("findRecursiveList", findId, start)
    return objList 

def objListIter(fromElement, findId, verbose, skipUnnamed, objList, depth):
    depth += 1

    if verbose:
        printObjIter(fromElement, depth)

    children = object.children(fromElement)
    for child in children:
        if hasattr(child, 'id'):
            if child.id == findId:
                objList.append(child)
        elif skipUnnamed:
            continue

        objList, depth = objListIter(child, findId, verbose, skipUnnamed, objList, depth)
        depth = depth - 1

    return objList, depth

# Utilities
def printElapsed(functionName, objectId, start):
    elapsed = time.time() - start
    test.log(functionName + " - " + objectId + " in " + str(elapsed) + "s.")

def printObjIter(element, depth):
    dashes = "-" * depth

    if hasattr(element, 'id'):
        test.log(dashes + " " + str(element.id))
    else:
        test.log(dashes + " [unnamed]")

问题 QML 的示例测试脚本:

startApplication("exampleapp") # Launch application binary 'exampleapp'
snooze(10) # Let it start

root = findRoot()
page = findFlat(root, "page", 1, True, False)
foobar = findFlat(page, "foobar", 1, True, False)

# Also just: foobar = findRecursive(root, "foobar", 1)

if foobar.text == "ipsum":
    test.passes("text is ok")
else:
    test.fail("Incorrect foobar text: " + foobar.text)
于 2014-09-02T11:39:22.427 回答
1

您也可以将存储在 ROOT_SYMBOLIC_OBJECT 中的符号名称“:_KMainView”替换为其真实名称,因为符号名称只是真实名称的占位符:

文章 - Squish 如何从符号名称中查找真实名称

于 2015-10-06T11:35:11.777 回答
0

语法应该是:findObject("{container=':_QQuickView' id='foobar' type='Text' visible='true'}")

您可以在[导航] -> [打开符号名称]中找到信息,然后选择元素并单击鼠标右键“复制真实名称”

于 2014-03-17T06:59:21.490 回答