Qt QML-如何在项目中获取子项?

Qt QML-如何在项目中获取子项?,qt,qml,qtquickcontrols2,Qt,Qml,Qtquickcontrols2,我对QML中的项目有问题。我想得到一个项目的孩子,但它似乎在第一个元素工作 详细代码如下: 我有一个gridview,其中列出了自定义组件AAA\U样式 我的自定义AAA_RTS是一个QML组件,具有以下功能: -功能 -功能 我使用 grdViewDeviceControl.model.append 我确保模型有我添加的数据,因为它出现在我的设计中,gridview的计数是2个元素 console.loggrdViewDeviceControl.count//结果为2 之后,我尝试使用按钮释

我对QML中的项目有问题。我想得到一个项目的孩子,但它似乎在第一个元素工作

详细代码如下:

我有一个gridview,其中列出了自定义组件AAA\U样式

我的自定义AAA_RTS是一个QML组件,具有以下功能: -功能 -功能 我使用

grdViewDeviceControl.model.append

我确保模型有我添加的数据,因为它出现在我的设计中,gridview的计数是2个元素

console.loggrdViewDeviceControl.count//结果为2

之后,我尝试使用按钮释放信号中的方法让每个元素访问它们可用的函数:

控制台上的结果:

qml:项目编号:2 qml:QQuickItem0x9828f60 qml:AAA_样式_qml类型_0_qml_1120x9829070,设备控制 qml:QQuickItem0x5554140 qml:未定义

使用第一个元素grdViewDeviceControl.contentItem.children[0],我成功访问了函数a或函数b,但使用第二个元素时出现了错误

TypeError:无法调用未定义的方法“function_a”

那么有谁能告诉我为什么我错了,以及如何修复它


非常感谢您的帮助

不要尝试直接访问子项。改用代理ID、信号和插槽:

通过GridView的模型为所有代理提供代理ID。 在GridView中,添加用于向所有学员广播以下内容的信号: 您希望它执行函数的委托的委托ID。 AAA_Styles函数的参数。 在代理中,为每个AAA_Styles函数添加一个插槽。仅当广播的委托ID是委托的:if broadcastedID==delegateID{function_ab}时,每个插槽才会执行AAA_Styles函数。 例如,当您想在委托中执行函数_a或函数_b时,可以通过onReleased中相应的GridView信号广播委托ID和函数参数。 下面的代码总结了我刚才向您描述的内容。如果它不起作用,则将委托放在一个单独的QML文件中。这应该是有益的:

// Your grid
GridView {
    id: grdViewDeviceControl
    clip: true
    interactive: true
    ScrollIndicator.vertical: ScrollIndicator {}
    cellWidth: 200
    cellHeight: 300

    model: ListModel {
        /*
            Example of list element:
            ListElement { m_uuid: "{element-uuid}" }
        */
    }

    delegate: Item {
        width: grdViewDeviceControl.cellWidth
        height: grdViewDeviceControl.cellHeight

        AAA_Styles {
            id: deviceControl
            objectName: "deviceControl"
            anchors.centerIn: parent
            name: Names
            subname: Subnames
        }

        // The delegate ID
        property string delegate_id: m_uuid

        // Broadcast receivers
        function delfunc_a(uuid, argA0) {
            if (uuid === this.delegate_id) {
                deviceControl.function_a(argA0)
            }
        }

        function delfunc_b(uuid, argB0, argB1) {
            if (uuid === this.delegate_id) {
                deviceControl.function_b(argB0, argB1)
            }
        }

        // Connecting broadcasters to receivers
        Component.onCompleted: {
            grdViewDeviceControl.exec_a.connect(this.delfunc_a)
            grdViewDeviceControl.exec_b.connect(this.delfunc_b)
        }

        Component.onDestruction: {
            grdViewDeviceControl.exec_a.disconnect(this.delfunc_a)
            grdViewDeviceControl.exec_b.disconnect(this.delfunc_b)
        }
    }

    // Your broadcasters
    signal exec_a(string uuid, int argA0)
    signal exec_b(string uuid, bool argB0, string argB1)
}

访问视图中的项是一种不好的做法,因为它会带来诸如您指出的内容之类的问题,相反,您应该与模型信息交互。为什么要访问这些项目?是的,我不知道最好的方法。感谢您的推荐以及如何访问该模型?我想我必须在gridview之外创建一个模型,并通过idExactly访问它,检查我的旧答案您指出的可能的解决方案可以工作,但我没有分析它,因为对我来说它不是正确的解决方案,因为它很难维护,例如,如果更改组件,则必须修改代码的另一部分。也就是说,您可能的解决方案是一个临时补丁,将来它会给您带来很多麻烦。当我开始使用QML时,我已经遇到了这些问题,我不想再遇到它们。对我来说,你有一个问题,那就是,你要求的是一个没有人保证有效的答案,而不是你的根本问题。我认为评论已经被扩展了。我要说的最后一件事是,在实现组件之前,首先要设计它们。很多时候,我们有一个坏习惯,就是编写代码时没有清楚地了解设计需要什么,再见
onReleased: {
    console.log("number of item: " + grdViewDeviceControl.count)
    var myRTS = grdViewDeviceControl.contentItem.children[0]
    console.log(myRTS)
    console.log(myRTS.children[0])
    myRTS = grdViewDeviceControl.contentItem.children[1]
    console.log(myRTS)
    console.log(myRTS.children[1])
}
// Your grid
GridView {
    id: grdViewDeviceControl
    clip: true
    interactive: true
    ScrollIndicator.vertical: ScrollIndicator {}
    cellWidth: 200
    cellHeight: 300

    model: ListModel {
        /*
            Example of list element:
            ListElement { m_uuid: "{element-uuid}" }
        */
    }

    delegate: Item {
        width: grdViewDeviceControl.cellWidth
        height: grdViewDeviceControl.cellHeight

        AAA_Styles {
            id: deviceControl
            objectName: "deviceControl"
            anchors.centerIn: parent
            name: Names
            subname: Subnames
        }

        // The delegate ID
        property string delegate_id: m_uuid

        // Broadcast receivers
        function delfunc_a(uuid, argA0) {
            if (uuid === this.delegate_id) {
                deviceControl.function_a(argA0)
            }
        }

        function delfunc_b(uuid, argB0, argB1) {
            if (uuid === this.delegate_id) {
                deviceControl.function_b(argB0, argB1)
            }
        }

        // Connecting broadcasters to receivers
        Component.onCompleted: {
            grdViewDeviceControl.exec_a.connect(this.delfunc_a)
            grdViewDeviceControl.exec_b.connect(this.delfunc_b)
        }

        Component.onDestruction: {
            grdViewDeviceControl.exec_a.disconnect(this.delfunc_a)
            grdViewDeviceControl.exec_b.disconnect(this.delfunc_b)
        }
    }

    // Your broadcasters
    signal exec_a(string uuid, int argA0)
    signal exec_b(string uuid, bool argB0, string argB1)
}
// Somewhere else in your code:
onReleased: {
    /*
     * Only the delegate whose ID is "{a-given-uuid}"
     * will execute deviceControl.function_a(3):
     */
    grdViewDeviceControl.exec_a("{a-given-uuid}", 3)
    /*
     * Only the delegate whose ID is "{another-given-uuid}"
     * will execute deviceControl.function_b(true, "U got style!"):
     */
    grdViewDeviceControl.exec_b("{another-given-uuid}", true, "U got style!")
}