Get property of component in another component

I am implementing tests system with QML. After pressing on some answer in section(e.g. question) property answered should change on true, so I will not be able to press answer in this section anymore. I check for that in answerDelegate MouseArea click handler. But I can't get access to answered property.

Any ideas how connect them?

Rectangle {
    id: root
    anchors.fill: parent

    property ListModel testModel: ListModel {}
    property int totalAnswers: 0
    property int questionsCount: 0   

    function setTestModel(tests){
        testModel.clear()
        testModel.append(tests)
    }

    ScrollView {
        id: testsScroll
        anchors.fill: parent

        ListView {
            id: testsView
            anchors.fill: parent
            model: testModel

            delegate: answersDelegate

            section.property: "question"
            section.delegate: questionDelegate
        }
    }

    Component {
        id: questionDelegate

        Rectangle{
            id: questionItem
            // the property I need to get access
            property bool answered: false
            width: parent.width
            height: 40

            Text {
                anchors.left: parent.left
                text: section
            }

            Component.onCompleted: {
                questionsCount += 1
            }
        }
    }

    Component {
        id: answersDelegate
        Item {
            id: oneItem
            width: parent.width
            height: 30

            Rectangle {
                id: answerRectangle

                Text {
                    anchors.left: parent.left
                    text: content
                }

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        // here I check it
                        root.answerClicked()
                        if (!questionDelegate.answered) {
                            questionDelegate.answered = true
                            answerRectangle.color = correct == true ? "#00ff00": "#ff0000"
                            if (correct) total += 1
                        }
                    }
                }
            }
        }
    }
}

Upvotes: 0

Views: 1341

Answers (1)

derM
derM

Reputation: 13711

You can't have access to a components property. A Component is not an instance. It is more like a factory, set up to produce any number of instances with the same configuration.

If you have the Component as a delegate of your ListView the ListView will create multiple instances, one per entry in the model, as long as it would fit in the view port. Now you would have more than one instance of the component and each instance might have a different value for your property. Which one would you expect to be read?

Therefore you can't use the ids of and within Components to access their internals. Instead you need to access the concrete instance you have created somewhere and read the properties of this instance.

Further you should note, that it is not advisable to set the state of delegates within the delegates as they are dynamically created and destroyed. If you'd set the answered-flag in the delegate (either the question- or answerDelegate) and then scroll, the answer might leave the view port, the delegate gets destroyed and the information is lost.

Instead write back the changes in the model, where they are more persistent.

Upvotes: 3

Related Questions