问题
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 theAAA_Styles
function only if the broadcasted delegate ID is the delegate's:if (broadcastedID === delegateID) { function_ab() }
. - When you want to execute
function_a()
orfunction_b()
in a delegate, broadcast the delegate ID and the function arguments through the correspondingGridView
signal (inonReleased
, 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