In Qt Quick, how to ensure a ListView's delegate's width to equal the view's width?
Asked Answered
C

2

5

Here's my QML view:

// Imports ommitted

Item {
    id: paymentMethods
    required property PaymentMethodsModel model

    ColumnLayout {
        anchors.fill: parent;

        Text {
            text: "Payment methods";
        }

        ListView {
            Layout.fillHeight: true
            Layout.fillWidth: true
            model: paymentMethods.model
            delegate: PaymentMethods.Item { }
        }

        ToolBar { }
    }
}

The problem is, it looks like this:

Application window with text and buttons all smooshed

I think it's because the delegate doesn't specify width, because if I do this:

        delegate: PaymentMethods.Item {
            width: parent.width
            onPmSaved: {
                ListView.view.model.rename(index, newName)
            }
        }

It looks much better:

Application window with text and buttons nicely separated

The problem is, when I do edits that reorder the items, I get this error:

qrc:/PaymentMethods.qml:32: TypeError: Cannot read property 'width' of null

Is there a good way to set a QML ListView's delegate's width to full parent's width?

Cremate answered 18/8, 2020 at 18:39 Comment(2)
Can you share minimal reproducible example?Middlesworth
@MaximSkvortsov Okay, I'll try!Cremate
T
8

From the ListView documentation:

Delegates are instantiated as needed and may be destroyed at any time. As such, state should never be stored in a delegate. Delegates are usually parented to ListView's contentItem, but typically depending on whether it's visible in the view or not, the parent can change, and sometimes be null. Because of that, binding to the parent's properties from within the delegate is not recommended. If you want the delegate to fill out the width of the ListView, consider using one of the following approaches instead:

ListView {
    id: listView
    // ...

    delegate: Item {
        // Incorrect.
        width: parent.width

        // Correct.
        width: listView.width
        width: ListView.view.width
        // ...
    }
}
Toad answered 18/9, 2020 at 1:11 Comment(0)
U
2

In the transition of the reordering, the item does not have a parent, so the error indicates it, a possible solution is to set the width of the item depending on whether it has a parent or not.

width: parent ? parent.width : 40 // default value
Upstage answered 18/8, 2020 at 19:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.