QML - How to get children in an item?

僤鯓⒐⒋嵵緔 提交于 2019-12-10 11:57:18

问题


I had a problem with the item in QML. I wanna get children of an item but it seems working in the first element.

The detail code is below:

I have a gridview with a list custom component AAA_Styles

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

    model: ListModel{}

    delegate: Item {
        width: grdViewDeviceControl.cellWidth
        height: grdViewDeviceControl.cellHeight
        AAA_Styles{
            id: deviceControl
            objectName: "deviceControl"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            name: Names
            subname: Subnames
    }
}

My custom AAA_RTS is a QML component have some functions such as:
- function_a()
- function_b()
I added 2 items into model using

grdViewDeviceControl.model.append()

I ensure the model have data that I added because It appeared in my design and the count of gridview is 2 elements

console.log(grdViewDeviceControl.count) //the result is 2

After that, I tried to get each element to access functions that they are available using a method in signal onRelease of a button:

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])
}

The result on console:

qml: number of item: 2
qml: QQuickItem(0x9828f60)
qml: AAA_Styles_QMLTYPE_0_QML_112(0x9829070, "deviceControl")
qml: QQuickItem(0x5554140)
qml: undefined

With the first element grdViewDeviceControl.contentItem.children[0], I access function_a or function_b successful but when I using the second the error appeared

TypeError: Cannot call method 'function_a' of undefined

So can anyone tell me why I wrong and how to fix it?

Many thanks for any help!


回答1:


Do not try to access directly to the child items. Use delegate IDs, signals and slots instead:

  • Give a "delegate ID" to all your delegates through the model of your GridView.
  • In your GridView, add signals that will be used to broadcast to all the delegates the following things:
    • The "delegate ID" of the delegate that you want it to execute the function.
    • The arguments for the AAA_Styles function.
  • In your delegate, add one slot per AAA_Styles function. Each slot will execute the AAA_Styles function only if the broadcasted delegate ID is the delegate's: if (broadcastedID === delegateID) { function_ab() }.
  • When you want to execute function_a() or function_b() in a delegate, broadcast the delegate ID and the function arguments through the corresponding GridView signal (in onReleased, for example).

The following piece of code sums up what I have just described to you. If it does not work put the delegate in a separated QML file. This should work for good:

// 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!")
}


来源:https://stackoverflow.com/questions/55520448/qml-how-to-get-children-in-an-item

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!