art-solopov
art-solopov

Reputation: 4755

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

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?

Upvotes: 6

Views: 2170

Answers (2)

pooya13
pooya13

Reputation: 2691

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
        // ...
    }
}

Upvotes: 9

eyllanesc
eyllanesc

Reputation: 244003

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

Upvotes: 2

Related Questions