0

I have a ListView with a simple model which in turn also has a model which is actually displayed:

ListView {
    Component.onCompleted: console.log("ListView height: " + height)
    model: ["1"]
    delegate: Column {
        Component.onCompleted: console.log("Inner delegate height: " + height)
        Repeater {
            model: ["A", "B"]
            delegate: Text {
                Component.onCompleted: console.log("Text height: " + height)
                text: modelData
            }
        }
    }
}

I can get the Text and the Column height. Even though ListModel knows the Column height, it still has zero height.

My question is: how to properly assign ListView the given size?

The program outputs:

qml: Text height: 14
qml: Text height: 14
qml: Inner delegate height: 28
qml: ListView height: 0
5
  • 2
    I don't think ListView adjusts its height to fit content. Since ListView derived from Flickable it have to be contentHeight, not height. So you have to set size of ListView manually, with anchors or layouts Commented Mar 30, 2015 at 6:26
  • By the way, why using ListView here? Just put the Column in a Flickable. Shorter, simpler code with the same visual outcome. Commented Mar 30, 2015 at 6:33
  • Thank you very much for your suggestions. Inspired by them, I expanded the code and posted it below. Commented Mar 30, 2015 at 15:55
  • @BaCaRoZzo: in the real-world scenario I need many nested loops and I think implementing the solution with a ListView will be easier. The example in the question was a bit unfortunate to show only one item, 1, in the outer model. Commented Mar 30, 2015 at 15:57
  • I see. Well, I've underestimated the problem and that's my fault. Good to know that you solved the issue. :) Commented Mar 30, 2015 at 17:19

1 Answer 1

1

Based on @folibis' suggestion, I changed the contentHeight and contentWidth properties when the delegate's height or width changes. After adding anchors to ListView, it perfectly works together with the encompassing item.

Here is the code:

ListView {
    anchors.fill: parent
    model: ["1", "2"]
    delegate: Column {
        onHeightChanged: ListView.view.contentHeight = height
        onWidthChanged: ListView.view.contentWidth = width
        Repeater {
            model: ["A", "B", "C", "D"]
            delegate: Text {
                text: modelData
            }
        }
    }
}

Inspired by @BaCaRoZzo's comment, if one would not need a ListView, the problem can solved without it:

Flickable {
    id: flickable
    anchors.fill: parent
    Column {
        Repeater {
            model: ["1", "2"]
            Column {
                onHeightChanged: flickable.contentHeight = height
                onWidthChanged: flickable.contentWidth = width
                Repeater {
                    model: ["A", "B", "C", "D"]
                    delegate: Text {
                        text: modelData
                    }
                }
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.