Stefan Monov
Stefan Monov

Reputation: 11732

QML: calling itemAt on Repeater returns null

My code:

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480

    Column {
        Row {
            Repeater {
                id: rectRepeater
                model: 3
                Rectangle {
                    width: 30
                    height: 30
                    color: "red"
                    radius: 10
                }
            }
        }
        Row {
            Repeater {
                model: 3
                Text {
                    text: rectRepeater.itemAt(0).width;
                }
            }
        }
    }
}

I get this error message:

TypeError: Cannot read property 'width' of null

I found this post saying that the solution is to use Component.onCompleted like this (just inserting a Component.onCompleted handler inside the Text object):

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480

    Column {
        Row {
            Repeater {
                id: rectRepeater
                model: 3
                Rectangle {
                    width: 30
                    height: 30
                    color: "red"
                    radius: 10
                }
            }
        }
        Row {
            Repeater {
                model: 3
                Text {
                    Component.onCompleted: {
                        text: rectRepeater.itemAt(0).width;
                    }
                }
            }
        }
    }
}

But this fails with the same error.

Any idea?

Upvotes: 1

Views: 3436

Answers (2)

Kevin Krammer
Kevin Krammer

Reputation: 5207

I would go for a conditional binding instead

Text {
    text: rectRepeater.count > 0 ? rectRepeater.itemAt(0).width : 0;
}

Once the rectRepeater has actually created at least one delegate, the value from that delegate is read. That works even if the rectRepeater's model becomes empty again at some point or if the item at index 0 changes its width

Upvotes: 2

Konstantin T.
Konstantin T.

Reputation: 1013

rectRepeater items is not exit when you call itemAt(0).

You should call itemAt when rectRepeater is instantiated.

Window {
    visible: true
    width: 640
    height: 480
    Column {
        Row {
            Repeater {
                id: rectRepeater
                model: 3
                Rectangle {
                    width: 30
                    height: 30
                    color: "red"
                    radius: 10
                }

            }
        }
        Row {
            Repeater {
                id: textrep
                model: 3
                Text {
                    }
            }
        }
        Component.onCompleted: {
            //Here all object are instantiated
            for (var i = 0; i< textrep.count; i++){
                textrep.itemAt(i).text = rectRepeater.itemAt(0).width
            }
        }
    }
}

Upvotes: 2

Related Questions