我有几个qml文件,每个文件都在我的应用程序中定义一个屏幕.有时,一个屏幕上的操作应该更改不同屏幕上的项目.现在我通过设置属性Item buttonId然后执行此操作
for (var i = 0; i < buttonId.parent.children.length; i++) {
buttonId.parent.children[i].state="inactive"
}
Run Code Online (Sandbox Code Playgroud)
是否可以直接访问不同文件中的项目/对象,例如通过他们的ID?
除非您有该 qml 类型的实例或单例,否则您无法访问“不同的 qml 文件”中的对象。
只有当试图访问它的对象是在它想要通过 id 访问的对象范围内创建时,才有可能通过 id 访问。
您有多个屏幕,只需将它们公开为根 qml 对象的属性,然后由于动态范围,它们将可以从整个应用程序访问,除非它们被具有相同名称的不同属性遮蔽。
正如dtech所说,你不能访问不同文件中的对象,因为它们还不是对象.
假设您有一个名为的文件 BlueSqare.qml
import QtQuick 2.0
Rectangle {
id: root
width: 100
height: 100
color: 'purple'
}
Run Code Online (Sandbox Code Playgroud)
现在你有了 main.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
ApplicationWindow {
id: root
width: 300
height: 300
visible: true
Row {
id: rowdi
spacing: 3
Repeater {
model: 3
delegate: BlueSquare {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
你会看到,它创建三个我的BlueSquare太是不确定的我想其中的一个改变,如果我设置root.color = 'blue'-或者实际上它是不是:因为我与其他对象id: root的main.qml,这就是ApplicationWindow,我将它的颜色为蓝色.
你可以看到:ids只需要在一个文件中是唯一的,因此你只能引用这个文件中的对象id.
可以免除这一点:您可以向上移动使用qml文件的文件树并引用它们的ID.
因此,如果您尝试在我的示例中引用rowdi,那么BlueSqure将引用Row它们来安排它们.这是可能的,因为您可以有一个定义良好的规则,您尝试通过此参考的对象id.
如果id在文件中找不到(此处为:BlueSquare.qml),则尝试引用它,然后它将查找实例化对象的文件(此处为:main.qml).如果它在那里找到它,搜索就结束了.如果找不到它,它会尝试移动一个文件 - 这在这里是不可能的,就像main.qml故事结束一样.
但是,如果可能,应该避免这种情况 也许你想在BlueSquare其他地方重复使用,而你没有Row那个也恰好拥有它id: rowdi.相反,你应该注入实例化的引用.
import QtQuick 2.0
import QtQuick.Controls 2.0
ApplicationWindow {
id: root
width: 300
height: 300
visible: true
Row {
id: rowdi
spacing: 3
property color squareColors: 'blue'
Repeater {
model: 3
delegate: BlueSquare {
color: rowdi.squareColors
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们id rowdi在我们定义它的文件中,将数据注入BlueSquares.
您也可以传递它们QtObject,将所有值保存为模型.如果您要更改值,这将特别有用:
// MyModelCountingButton.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
Button {
property QtObject model // Better would be to be more specific the QtObject and have a object that guarantees to have your properties
text: model ? model.count : '-'
onClicked: {
if (model) model.count++
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的 main.qml
import QtQuick 2.0
import QtQuick.Controls 2.0
ApplicationWindow {
id: root
width: 800
height: 600
visible: true
QtObject {
id: myCountingModel
property int count: 0
}
MyModelCountingButton {
id: button1
model: myCountingModel
}
MyModelCountingButton {
id: button2
model: myCountingModel
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用通用模型更改将影响其他对象的值,而无需引用自己文件之外的内容,从而提高了可重用性.
基本上,uppon实例化,你告诉他们从哪里读取和存储他们的数据,如果这个地方在你的屏幕之间共享,你就赢了.
对于您的问题,最简单的方法是currentIndex在模型中使用-property,为每个屏幕分配一个索引然后在文件中
// Screen.qml
[...]
Item {
id: root
property int index
property QtObject indexObject
Binding {
target: root
property: 'state'
value: 'inactive'
when: index !== indexObject.currentIndex
}
}
Run Code Online (Sandbox Code Playgroud)
并在 main.qml
[...]
ApplicationWindow {
[...]
QtObject {
id: indexObject
property int currentIndex: 0
}
Screen {
index: 0
indexObject: indexObject
}
Screen {
index: 1
indexObject: indexObejct
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
或者您将屏幕视为:
[...]
Item {
id: root
property int index
property int currentIndex
signal turningActive // this must be emitted when you want to have this screen active.
Binding {
target: root
property: 'state'
value: 'inactive'
when: index !== indexObject.currentIndex
}
}
Run Code Online (Sandbox Code Playgroud)
main.qml
[...]
ApplicationWindow {
id: root
[...]
property int currentIndex: 0
Screen {
index: 0
currentIndex: root.currentIndex
onTuringActive: root.currentIndex = 0
}
Screen {
index: 1
currentIndex: root.currentIndex
onTurningActive: root.currentIndex = 1
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
通常,如果只有少数属性,则创建声明其实例化的绑定.如果有大量数字,QtObject那么模型是有益的.
只有当你真的确定在哪个上下文中将始终使用声明的组件时,你才能考虑引用来自另一个文件的东西(例如parent在文件的根节点中使用或使用id需要的s)在另一个文件中解决)