访问不同qml文件中的项目

num*_*her 0 qt qml

我有几个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?

dte*_*ech 6

除非您有该 qml 类型的实例或单例,否则您无法访问“不同的 qml 文件”中的对象。

只有当试图访问它的对象是在它想要通过 id 访问的对象范围内创建时,才有可能通过 id 访问。

您有多个屏幕,只需将它们公开为根 qml 对象的属性,然后由于动态范围,它们将可以从整个应用程序访问,除非它们被具有相同名称的不同属性遮蔽。


der*_*erM 6

正如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: rootmain.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)在另一个文件中解决)