gpt4 book ai didi

qt - QML中ID的范围是什么?

转载 作者:行者123 更新时间:2023-12-01 08:22:52 60 4
gpt4 key购买 nike

文档说我们不能拥有 同号在一个文件中。这意味着我们可以在不同的文件中拥有相同的 id,对吗?我不知道QML中ID的范围,所以我写了如下代码来测试它。

//a.qml
Item {
id: a_item
x:20;
y:b_item.x // cannot access this id
y:b1.x1 // can access
Item {
id:a1
x:20
Component.onCompleted : a1.x //this a1 is a.qml's a1 not the a1 in main.qml
}
}

//b.qml
Item {
id: b_item
x:20;
property int x1: 30;
}

//main.qml
Item {
a {
id:a1
Component.onCompleted : b1.x = 1 //can access
}
b {
id:b1
}
function() {
a_item.x = 1; // cannot access this id
}
}

我的问题 :

1.

QML中ID的范围是什么?在我的测试中,结果显示Item无法访问其childen和他兄弟的children的id,但可以访问他的 parent 或兄弟 , 对?

2.

同号不同的文件 只是我在我的代码中显示,没有错误并且我工作了。但是我怎么能 区分他们。

最佳答案

规范的答案是:

The scope of ids is the component scope.



组件范围是:

Each QML component in a QML document defines a logical scope. Each document has at least one root component, but can also have other inline sub-components. The component scope is the union of the object ids within the component and the component's root object's properties.



这本身并没有过多地说明范围究竟是什么以及如何最佳利用它。多一点信息:

In QML, component instances connect their component scopes together to form a scope hierarchy. Component instances can directly access the component scopes of their ancestors.



基本上每个 id在 qml 文件中实现有点像该源的根项目的属性。除非它不能通过 someobj.someId 访问,仅通过 someId .

这意味着由于 qml 的动态范围,从根对象扩展的分支中存在的任何对象都可以访问此 id。

只要它没有被同名的 id 遮挡。或 property .
a_item将在 a.qml 中可见以及存在于其根分支中的任何对象 Item成长。

main.qml 看不到它由于该对象位于树的下方,其中 a_item没有定义。

同理, b1可以从 a.qml 访问因为 b1main.qml 中定义这是哪里 a.qml被实例化。但是 b_item将要
从那里看不到。

事实上,由于 a1b1main.qml 中定义这是整个应用程序树的根,这两个 id s 将从应用程序的每个对象可见,只要它是对象树的一部分并且标识符没有被隐藏。请注意,它们在单例对象或无父对象中是不可见的,因为它们不是应用程序对象树的一部分。
obj tree                a1  b1  a_item  b_item
main.qml D D X X
a.qm V V D X
Item a1 V V V X
b.qml V V X D

D - defined here, V - visible here, X - not available

属性也是如此,尽管动态范围仅适用于为 qml 文件根元素定义的属性,与 id 不同。 s 即使它们在不同的子分支上也是可见的,这就是为什么在这个答案的第一句话中我把它作为“实现的那种源的根项目的属性”:
Obj
Obj
Obj
id: objid
property objprop
CustomObj

所以 objid将在 CustomObj 中可见,但是 objprop不会,因为它不是一个 id,也不是在根对象中定义的。 id与这样做相同:
Obj
property objid : _objid
Obj
Obj
id: _objid

全部 id来自给定源的 s 在 qml 源根对象的上下文中可见,随后所有其他最终会下降到此上下文的所有内容,因为它查找无法解析“更高”上下文中的标识符。

最后,请记住一个微妙的陷阱 - 只能使用 id如果您确定您的应用程序将在兼容的上下文树中实例化对象,则跨源。

例如:
A.qml {
id: objA
B { } // objA will be visible to this object
}

main.qml
A {
B {} // objA will NOT be visible to this object
}
B {} // objA will NOT be visible to this object

陷阱还在继续 - 上下文树在对象树之前 - 创建对象的上下文很重要, 设置后不可更改 (根据上下文相关性对重新 parent 化设置了一定的限制)。
// ObjA.qml
Item {
id: objA
Component {
id: cm
ObjB {}
}
function create() { cm.createObject(objA) }
}

// ObjB.qml
Item {
Component.onCompleted: console.log(objA)
}

// main.qml
Component {
id: cm
Rect {}
}

Obj {
anchors.fill: parent
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button === Qt.LeftButton) {
cm.createObject(parent)
} else {
parent.create()
}
}
}
}

正如这个实际示例所示,即使在这两种情况下,新创建的对象都是具有 objA 的同一个对象的父对象。标识符,在 main.qml 中创建的对象无法解析它,因为它是在 objA 的上下文中创建的仍然没有定义,但如果对象是在 objA 的上下文中创建的,它就可以工作。 ,即使它在树上被刺得更高,它也会起作用。

用更通用的方式来说,是 id在源的根对象的上下文中变得可见,并在每个后续子上下文中保持可见,直到它被同名对象遮蔽为止。可见性无法沿着树向下到达在上下文 id 之前存在的上下文。中定义。
注意细微的差别 - a_item指的是 Itema1指的是 a .从 a1在内部可见 a.qml它将始终引用 a 的一个实例这是在 main.qml ,无论 a 的哪个实例你可能在,而 a_item将为 a 的每个不同实例引用不同的对象. a_item是“相对的”,并且在 a 的每个不同实例中都会有所不同但是 a1是绝对的,并且总是指向 a 的特定实例.这是因为 a1是一个具体实例,而 a_item是一个类型/原型(prototype)。
// Obj.qml
Item {
id: obj
Component.onCompleted: console.log(obj === oid)
}

// main.qml
Obj { } // false
Obj { id: oid } // true
id 的动态范围s 非常有用,可以减少实现变通方法以访问所需内容所需的时间。这也是为什么提供 id 是一个很好的主意的原因。描述性名称而不仅仅是 main .

例如,如果您有一个 manager管理多个 views ,每个都有一个 objects在其中,您可以快速访问各自的 view每个 object并且还可以访问经理而无需实现任何额外的东西。经验法则是 manager必须先来,然后每个 view应该在 manager 的上下文中创建,不一定直接在其中,但仍然在其中,并且每个 object应该在 view 的上下文中创建.当然,要注意不要遮蔽事物。如果您违反该规则,事情将无法正确解决。
View.qml { id: view }

manager
view1
object // view is view1
view2
object // view is view2
view3
object // view is view3

自然,这仅在您知道上下文树的一般结构将是什么样的特定目的设计中才有意义。如果您正在制作几乎可以随处使用的通用元素,您应该 绝对不是依赖访问 id s 跨源,您应该通过属性、别名等实现更通用的使用接口(interface)。

关于qt - QML中ID的范围是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49311267/

60 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com