树类型对象
针对树控件以及树中的节点,模型管理器提供了Tree
和TreeItem
两个控件。Tree
控件代表整棵树,而TreeItem
代表树中的各个节点。由于节点的名称并不唯一,因此将节点名称作为识别属性是不可靠的,模型管理器提供了一个描述节点位置的识别属性——itemPath
,可以点击itemPath属性查看具体介绍。
针对树件还提供了相应的演练——演练:操作Qt应用中的List,能够大大加深对于API的理解程度。
树状视图控件: Tree
针对Tree
控件,大多是以传入itemPath
来操作相关节点;而TreeItem
控件自身本来代表的就是节点,因此对其操作通常情况下不需要传参数。
方法名 | 描述 |
---|---|
getItem | 返回TreeItem对象 |
findItem | 搜索文本,并返回TreeItem对象,如果搜索不到返回null |
scrollTo | 滚动到指定的项 |
scrollToTop | 滚动到顶部 |
scrollToBottom | 滚动到底部 |
select | 选中指定位置的树节点 |
collapseAll | 按完整树路径闭合树节点, 路径名可以是索引或名称 |
columnData | 返回列数据 |
children | 顶层TreeItem元素 |
childCount | 顶层元素数量 |
rowData | 返回索引所在的行数据 |
columnCount | 获取列表列数 |
columnHeaders | 返回表格列标题的数组 |
类型定义
export interface IQTree extends IQtControl {
getItem(itemPath: ItemPath): IQTreeItem;
findItem(text: string): Promise<IQTreeItem | null>;
scrollTo(itemPath: ItemPath): Promise<IQTreeItem>;
scrollToTop(): Promise<void>;
scrollToBottom(): Promise<void>;
collapseAll(itemPath: ItemPath): Promise<void>;
columnData(nameOrIndex: number | string): Promise<string[]>;
select(itemPath: ItemPath): Promise<IQTreeItem | null>;
children(): Promise<IQTreeItem[]>;
childCount(): Promise<number>;
rowData(itemPath: ItemPath): Promise<string[]>;
columnCount(): Promise<number>;
columnHeaders(): Promise<string[]>;
}
export type ItemPath = (number | [number, number])[];
class QTree(QtControl):
def columnHeaders() -> List[str]
def collapseAll(itemPath: TypedDict) -> None
def getItem(itemPath: TypedDict) -> "QTreeItem"
def findItem(text: str, options: Optional[FindItemOptional]=None) -> "QTreeItem"
def rowData(itemPath: TypedDict) -> List[str]
def columnData(nameOrIndex: Union[str, int]) -> List[str]
def select(itemPath: TypedDict) -> "QTreeItem"
def childCount() -> int
def children() -> List[QTreeItem]
def columnCount() -> int
def scrollToTop() -> None
def scrollTo(itemPath: TypedDict) -> "QTreeItem"
def scrollToBottom() -> None
对象操作API
下面是针对Tree
控件的对象操作API。
getItem(itemPath): IQTreeItem
获取指定itemPath
位置的树节点对应的自动化对象。
参数
- itemPath:
ItemPath
型,代表节点的位置。
返回值
IQTreeItem
类型,即TreeItem
控件的自动化对象。注意这是一个同步方法,不需要await
关键字,也不会匹配应用中的控件。只有在执行对象上的异步方法时才会进行匹配。
示例代码
await model.getTree("Dir_View").getItem()
model.getTree("Dir_View").getItem()
findItem(text: string): Promise<IQTreeItem | null>
在树中根据名称搜索目标树节点,返回目标树节点的自动化对象,如果没有搜索到则返回null
。由于需要实时的搜索应用中的树,因此是异步方法。
参数
- text:
string
类型,期望目标树节点的内容或者文本;
返回值
Promise<IQTreeItem>
或Promise<null>
类型,搜索应用中的目标树节点,如果没有搜索到则返回null
。findItem()的搜索策略:
findItem()
方法采取的是“广度优先”的搜索策略,即先在当前层级中搜索满足条件(即符合名称的树节点);如果全都不满足,才会进入下一层级。如果是未展开的节点,那么通常不会被搜索到,因此如果是需要获取比较深层的树节点,最佳的方式还是一层一层的调用findItem()
方法来保证所有的节点都可以被正确搜索到。对此,树节点也提供了findItem()方法。
示例代码
await model.getTree("Dir_View").findItem("Qt")
model.getTree("Dir_View").findItem("Qt")
select(itemPath): Promise<void>
选中指定位置的树节点。
参数
- index:
ItemPath
型,目标节点的索引。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTree("Dir_View").select([0,1])
model.getTree("Dir_View").select([0,1])
scrollToTop(): Promise<void>
滚动到树的顶部。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTree("Dir_View").scrollToTop()
model.getTree("Dir_View").scrollToBottom()
scrollTo(itemPath): Promise<IQTreeItem>
滚动到目标树节点的位置,并返回此对象。如果目标位置还未展开,会一直展开到目标节点使其可见为止。
参数
- itemPath:
ItemPath
型,目标节点的位置。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTree("Dir_View").scrollTo([0,1])
model.getTree("Dir_View").scrollTo([0,1])
scrollToBottom(): Promise<void>
滚动到树的底部。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTree("Dir_View").scrollToBottom()
model.getTree("Dir_View").scrollToBottom()
collapseAll(itemPath: ItemPath): Promise<void>
折叠指定路径上的所有树节点。
参数
- itemPath:
ItemPath
型,目标节点的位置。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTree("Dir_View").collapseAll()
model.getTree("Dir_View").collapseAll()
children(): Promise<IQTreeItem[]>
获取当前树的所有的直系子节点,以数组的形式返回。
返回值
- 由
TreeItem
类型的自动化对象组成的数组。并且是异步方法,需要使用await
关键字。
示例代码
await model.getTree("Dir_View").children()
model.getTree("Dir_View").children()
childCount(): Promise<number>
获取当前树的所有的直系子节点的数量,返回数字。
返回值
number
类型,直系子节点的数量,可以理解为children()
方法返回的数组的长度。并且是异步方法,需要使用await
关键字。
示例代码
const count = await model.getTree("Dir_View").childCount()
console.log(count)
count = model.getTree("Dir_View").childCount()
print(count)
rowData(itemPath: ItemPath): Promise<string[]>
获取目标树节点的所有属性,并以数组形式返回。
参数
- itemPath:
ItemPath
型,目标节点的位置。
返回值
string[]
类型,由树节点的属性构成的字符串数组。比如针对文件树,某个文件节点的属性可能包含了
[文件名, 文件大小, 文件类型, 最后修改时间]
这些值。
示例代码
const rowData = await model.getTree("Dir_View").rowData([0,1])
console.log(rowData)
rowData = model.getTree("Dir_View").rowData([0,1])
print(rowData)
columnData(nameOrIndex): Promise<string>
获取树的某列属性的全部数据,允许指定列的名称或是索引。可选的列名或索引可以参考columnHeaders()
方法的返回值。
出于性能和使用场景考虑,只获取顶层树节点的数据。
返回值
string[]
类型,该列的全部属性。
示例代码
const columnData = await model.getTree("Dir_View").columnData("文件名")
console.log(columnData)
columnData = model.getTree("Dir_View").columnData("文件名")
print(columnData)
columnHeaders(): Promise<string[]>
获取树的属性名称,也就是树中每一列的列头内容,并以字符串数组的形式返回。
如果希望进一步的操作树的属性标题行,可以参考表格中的表头控件HeaderItem的操作。
返回值
string[]
类型,由属性名称组成的字符串数组。
示例代码
const columnHeaders = await model.getTree("Dir_View").columnHeaders()
console.log(columnHeaders)
columnHeaders = model.getTree("Dir_View").columnHeaders()
print(columnHeaders)
columnCount(): Promise<number>
获取树的属性个数,也就是树中有几列。在数值上等于columnHeaders()
方法返回数组的长度。
返回值
number
类型,属性个数。
示例代码
const columnCount = await model.getTree("Dir_View").columnCount()
console.log(columnCount)
columnCount = model.getTree("Dir_View").columnCount()
print(columnCount)
树节点控件: TreeItem
针对树中每个节点控件的自动化对象TreeItem
,可以对它展开或折叠,获取它的子节点等等操作。
相比于上一节中所有大部分树节点操作都要传入itemPath
参数来定位被操作的树节点,
方法名 | 描述 |
---|---|
select | 选中当前控件 |
getItem | 提供相对于当前TreeItem的相对路径,返回子树中的某个TreeItem |
findItem | 搜索文本,并返回TreeItem对象,如果搜索不到返回null |
expand | 展开当前节点 |
collapse | 折叠当前节点 |
scrollIntoView | 滚动到视图位置 |
set | 设置当前节点的内容 |
toggleCheck | 设置选中的值: "true" 为选中, "false" 取消选中,"partial"部分选中 |
data | 传入role,返回树节点数据内容,不传使用缺省role=DisplayRole |
exists | 检查控件是否存在,其中time为重试时间,以秒为单位。缺省重试秒数为0,即只检查1次 |
value | 控件值 |
rowData | 返回该节点行数据 |
rowItems | 返回包含当前行的所有树节点对象数组 |
expandable | 是否能展开 |
editable | 是否可编辑 |
selected | 当前节点是否被选中 |
expanded | 当前节点是否展开 |
childCount | 当前节点的子节点数量 |
children | 子节点数组 |
rowIndex | 当前节点的行号 |
columnIndex | 当前节点的列号 |
itemPath | 以名称数组返回TreeItem的路径信息,useIndex为true时使用节点索引 |
checkState | 检查控件是否被选中,"true"选中,"false"未选中,"partial"部分选中 |
类型定义文件
类型定义文件如下:
export interface IQTreeItem extends IQtControl {
select(): Promise<void>;
getItem(itemPath: ItemPath): IQTreeItem;
findItem(text: string): Promise<IQTreeItem | null>;
expand(): Promise<void>;
collapse(): Promise<void>;
scrollIntoView(): Promise<void>;
set(value: string): Promise<void>;
toggleCheck(checkState: boolean | 'partial'): Promise<void>;
data(roleId?: number): Promise<string|int>;
exists(seconds: number): Promise<boolean>;
value(): Promise<string>;
rowData(): Promise<string[]>;
rowItems(): Promise<IQTreeItem[]>;
expandable(): Promise<boolean>;
editable(): Promise<boolean>;
selected(): Promise<boolean>;
expanded(): Promise<boolean>;
childCount(): Promise<number>;
children(): Promise<IQTreeItem[]>;
rowIndex(): Promise<number>;
columnIndex(): Promise<number>;
itemPath(): Promise<ItemPath>;
checkState(): Promise<boolean | 'partial'>;
}
class QTreeItem(QItemViewItem):
def expand() -> None
def collapse() -> None
def exists(seconds: int) -> bool
def value() -> str
def rowData() -> List[str]
def rowItems() -> List[QTreeItem]
def scrollIntoView() -> None
def set(value: str) -> None
def data(roleId: int = None) -> Union[str, int]
def select() -> None
def expandable() -> bool
def expanded() -> bool
def childCount() -> int
def children() -> List[QTreeItem]
def rowIndex() -> int
def columnIndex() -> int
def itemPath() -> TypedDict
def getItem(itemPath: TypedDict) -> "QTreeItem"
def findItem(text: str, options: Optional[FindItemOptional]=None) -> "QTreeItem"
def checkState() -> Union[bool, str]
def toggleCheck(checkState: Union[bool, str]) -> None
对象操作API
value(): Promise<string>
获得树节点的名称。
返回值
Promise<string>
类型,表示树节点的名称。需要使用await
关键字取出其中的结果。
示例代码
校验获取树节点temp
控件的控件值。
let value = await model.getTreeItem("temp").value();
assert.equal(value,'temp');
value = model.getTreeItem("temp").value()
assert value == 'temp'
getItem(itemPath): IQTreeItem
获取以当前节点为起点,指定itemPath
位置的树节点对应的自动化对象。相比于Tree
对象上的getItem()
方法需要传入完整的itemPath
才能索引到目标节点,TreeItem
对象的getItem()
方法会自动的将传入的itemPath
与当前树节点的itemPath
属性拼接后再进行索引,实现类似相对路径的效果。
参数
- itemPath:
ItemPath
型,代表目标节点相对当前节点的位置。
返回值
IQTreeItem
类型,即TreeItem
控件的自动化对象。注意这是一个同步方法,不需要await
关键字,也不会匹配应用中的控件。只有在执行对象上的异步方法时才会进行匹配。
假设TreeItem
对象A的itemPath
属性为[0,1]
,那么脚本调用getTreeItem("A").getItem([2,3])
时,会将两者的itemPath
进行拼接,等效于getTree("Tree").getItem([0,1,2,3])
。
示例代码
await model.getTreeItem("W_(C:)").getItem([0,1])
model.getTreeItem("W_(C:)").getItem([0,1])
findItem(text: string, options?:object): Promise<IQTreeItem | null>
根据名称搜索目标树节点,返回目标树节点的自动化对象TreeItem
,默认采取模糊搜索,不区分大小写,返回部分匹配的第一个结果,如果没有搜索到则返回null
。
虽然采取模糊匹配,但是如果有完全匹配的结果,则会最优先返回,无论是作为第几个结果。
参数
- text:
string
类型,期望目标列表项的内容或者文本; - options: (可选)搜索选项。
- exact: 精确匹配选项,
boolean
类型,默认为false
。设为true
后会从模糊搜索改为精确搜索,只返回完全匹配的第一个结果,否则返回null
。
- exact: 精确匹配选项,
返回值
Promise<IQTreeItem>
或Promise<null>
类型,搜索应用中的目标单元格,如果没有搜索到则返回null
。对于展开后才开始加载子节点的树,搜索前先展开当前节点可以避免无法找到子节点的情况。
示例代码
let item = await model.getTreeItem("temp").findItem("123");
assert.equal(await item.value(),"123");
item = model.getTreeItem("temp").findItem("123")
assert item.value() == '123'
scrollIntoView(): Promise<void>
滚动到树节点位置。如果树节点所在的位置被折叠,则会展开所有路径上的树节点。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTreeItem("temp").scrollIntoView();
model.getTreeItem("temp").scrollIntoView()
select(): Promise<void>
选中树节点。如果该节点不在可视范围内,还会自动的滚动到该项所在的位置。
这个方法当节点不在不在可视范围内时,会自动的执行
scrollIntoView()
方法来展开并滚动到目标节点。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTreeItem("temp").select();
model.getTreeItem("temp").select()
expand(): Promise<void>
展开树节点,如果是无法展开的节点,则不会有任何效果。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTreeItem("temp").expand();
model.getTreeItem("temp").expand()
collapse(): Promise<void>
展开树节点,如果是无法折叠的节点,则不会有任何效果。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTreeItem("temp").collapse();
model.getTreeItem("temp").collapse()
set(value: string): Promise<void>
修改树节点的值,如果是无法编辑的节点,则不会有任何结果。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTreeItem("temp").set("123");
model.getTreeItem("temp").set("123")
toggleCheck(checkState: boolean | 'partial'): Promise<void>
选中或是取消选中树节点中的复选框。
参数
- checkState:
boolean
类型或是partial
字符串。true
代表选中,false
代表未选中,"partial"
代表部分选中(常见于含子选项的复选框)。
返回值
- 不返回任何值的异步方法。
示例代码
await model.getTreeItem("temp").toggleCheck(true);
model.getTreeItem("temp").toggleCheck(true)
data(roleId?:number): Promise<string|int>
传入role,返回树节点数据内容,不传使用缺省role=DisplayRole
返回值
string
类型或是int
类型数据内容。
示例代码 role值可参考enum Qt::ItemDataRole
获取树节点的文本数据内容:
const { RunSettings } = require("leanpro.common");
const { QtAuto } = require("leanpro.qt");
(async () => {
await RunSettings.set({slowMo: 1000, reportSteps: true});
let modelQt = QtAuto.loadModel(__dirname + "/recording_1.tmodel");
await QtAuto.launchQtProcessAsync("C:\\Program Files\\LeanPro\\CukeTest\\bin/dirview.exe");
const role = 0;
console.log(await modelQt.getTreeItem("C:").data(role));
console.log(await modelQt.getTreeItem("TreeItem").data(role));
console.log(await modelQt.getTreeItem("Drive").data(role));
console.log(await modelQt.getTreeItem("2023/7/24_18:40:46").data(role));
})();
import os
from leanproAuto import RunSettings, QtAuto
RunSettings.set({"slowMo": 1000, "reportSteps": True})
modelQt = QtAuto.loadModel(os.path.dirname(os.path.realpath(__file__)) + "/recording_4.tmodel")
QtAuto.launchQtProcessAsync("C:\\Program Files\\LeanPro\\CukeTest\\bin\\dirview.exe")
role = 0
modelQt.getApplication("dirview").exists(10)
print(modelQt.getTreeItem("C:").data(role))
print(modelQt.getTreeItem("TreeItem").data(role))
print(modelQt.getTreeItem("Drive").data(role))
print(modelQt.getTreeItem("2023/7/24_18:40:46").data(role))
exists(seconds: number): Promise<boolean>
当前树节点是否在已展开的树中,传入参数为等待时间。
参数
- seconds:
number
类型,等待时间,如果超过等待时间仍然为false
,则返回。
返回值
boolean
类型,是否存在。
示例代码
await model.getTreeItem("temp").exists(5);
model.getTreeItem("temp").exists(5)
children(): Promise<IQTreeItem[]>
获取当前树节点的所有的直系子节点,以数组的形式返回。
返回值
- 由
TreeItem
类型的自动化对象组成的数组。并且是异步方法,需要使用await
关键字。
示例代码
let children = await model.getTreeItem("temp").children();
for(let item of children){
console.log(await item.text());
}
children = model.getTreeItem("temp").children()
for item in children:
print(item.text())
rowIndex(): Promise<number>
获取当前树节点的在直系父节点中的行索引位置。
返回值
number
类型,单元格中的行索引位置。
示例代码
const rowIndex = await model.getTreeItem("temp").rowIndex();
assert.equal(rowIndex, 0);
rowIndex = model.getTreeItem("temp").rowIndex()
assert rowIndex == 0
columnIndex(): Promise<number>
获取当前树节点的在直系父节点中的列索引位置。
返回值
number
类型,单元格中的列索引位置。
示例代码
const columnIndex = await model.getTreeItem("temp").columnIndex();
assert.equal(columnIndex, 0);
columnIndex = model.getTreeItem("temp").columnIndex()
assert columnIndex == 0
itemPath(): Promise<ItemPath>
树节点的位置。
返回值
ItemPath
类型,代表树节点的位置。
示例代码
const itemPath = await model.getTreeItem("temp").itemPath();
console.log(itemPath);
itemPath = model.getTreeItem("temp").itemPath()
print(itemPath)
childCount(): Promise<number>
获取当前树节点的所有的直系子节点的数量,返回数字。
返回值
number
类型,直系子节点的数量,可以理解为children()
方法返回的数组的长度。并且是异步方法,需要使用await
关键字。
示例代码
const childCount = await model.getTreeItem("temp").childCount();
assert.equal(childCount, 2);
childCount = model.getTreeItem("temp").childCount()
assert childCount == 2
rowData(): Promise<string[]>
获取树节点的所有属性,并以数组形式返回。
返回值
string[]
类型,由树节点的属性构成的字符串数组。比如针对文件树,某个文件节点的属性可能包含了
[文件名, 文件大小, 文件类型, 最后修改时间]
这些值。
示例代码
const rowData = await model.getTreeItem("temp").rowData();
console.log(rowData);
rowData = model.getTreeItem("temp").rowData()
print(rowData)
rowItems(): Promise<QTreeItem[]>
获取与当前树节点处于同一行的所有树节点,以数组的形式返回。
返回值
- 由指定TreeItem处于同一行的所有TreeItem对象组成的数组。并且是异步方法,需要使用
await
关键字。
示例代码
const rowItems = await model.getTreeItem("temp").rowItems();
for(let item of rowItems){
console.log(await item.value());
}
rowItems = model.getTreeItem("temp").rowItems()
for item in rowItems:
print(item.value())
expandable(): Promise<boolean>
树节点是否可以被展开,可展开为true
,不可展开为false
。
返回值
boolean
类型,是否可展开。
示例代码
const expandable = await model.getTreeItem("temp").expandable();
assert.equal(expandable, true);
expandable = model.getTreeItem("temp").expandable()
assert expandable == True
editable(): Promise<boolean>
树节点是否可以被编辑,可编辑为true
,不可编辑为false
。
返回值
boolean
类型,是否可编辑。
示例代码
const editable = await model.getTreeItem("temp").editable();
assert.equal(editable, true);
editable = model.getTreeItem("temp").editable()
assert editable == True
expanded(): Promise<boolean>
树节点的展开情况,已展开为true
,未展开(折叠)为false
。
返回值
boolean
类型,是否已展开。
示例代码
const expanded = await model.getTreeItem("temp").expanded();
assert.equal(expanded, true);
expanded = model.getTreeItem("temp").expanded()
assert expanded == True
selected(): Promise<boolean>
树节点的选中情况,已选中为true
,未选中(折叠)为false
。
返回值
boolean
类型,是否已选中。
示例代码
const selected = await model.getTreeItem("temp").selected();
assert.equal(selected, true);
selected = await model.getTreeItem("temp").selected()
assert selected == True
checkState(): Promise<boolean | 'partial'>
获取列表项中的树节点选中状态。
返回值
boolean
类型或是partial
字符串。true
代表选中,false
代表未选中,"partial"
代表部分选中(常见于含子选项的复选框)。
示例代码
const state = await model.getTreeItem("temp").checkState();
assert state == true;
selected = await model.getTreeItem("temp").checkState()
assert selected == True