diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/quick/doc/snippets/qml/listview/stateInDelegate.qml | 20 | ||||
| -rw-r--r-- | src/quick/doc/snippets/qml/listview/stateInModel.qml | 26 | ||||
| -rw-r--r-- | src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc | 6 | ||||
| -rw-r--r-- | src/quick/items/qquicklistview.cpp | 24 |
4 files changed, 73 insertions, 3 deletions
diff --git a/src/quick/doc/snippets/qml/listview/stateInDelegate.qml b/src/quick/doc/snippets/qml/listview/stateInDelegate.qml new file mode 100644 index 0000000000..29d8d3e7c2 --- /dev/null +++ b/src/quick/doc/snippets/qml/listview/stateInDelegate.qml @@ -0,0 +1,20 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls.Basic + +//! [ListView] +ListView { + anchors.fill: parent + model: 3 + delegate: CheckDelegate { + text: qsTr("Channel %1").arg(index + 1) + + required property int index + property bool channelActivated + + onClicked: channelActivated = checked + } +} +//! [ListView] diff --git a/src/quick/doc/snippets/qml/listview/stateInModel.qml b/src/quick/doc/snippets/qml/listview/stateInModel.qml new file mode 100644 index 0000000000..56b2792140 --- /dev/null +++ b/src/quick/doc/snippets/qml/listview/stateInModel.qml @@ -0,0 +1,26 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls.Basic + +//! [ListView] +ListView { + anchors.fill: parent + model: ListModel { + ListElement { + channelActivated: true + } + // ... + } + delegate: CheckDelegate { + text: qsTr("Channel %1").arg(index + 1) + checked: model.channelActivated + + required property int index + required property var model + + onClicked: model.channelActivated = checked + } +} +//! [ListView] diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc index c2f085c314..4d7004e723 100644 --- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc +++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc @@ -181,6 +181,12 @@ to a \e {.qml} file. \li \l{Qt Design Studio: UI Files} \endlist +\section1 Using Qt Quick Views + +\section2 Store State in Models + +See \l {Avoid Storing State in Delegates}. + \section1 Using Qt Quick Layouts Qt offers Qt Quick Layouts to arrange Qt Quick items visually in a layout. diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 54b1157881..18a9495005 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -2086,7 +2086,7 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject * The list view itself is a focus scope (see \l{Keyboard Focus in Qt Quick} for more details). Delegates are instantiated as needed and may be destroyed at any time. - As such, state should \e never be stored in a delegate. + As such, \l {Avoid Storing State in Delegates}{state should \e never be stored in a delegate}. Delegates are usually parented to ListView's \l {Flickable::contentItem}{contentItem}, but typically depending on whether it's visible in the view or not, the \e parent can change, and sometimes be \c null. Because of that, binding to @@ -2224,8 +2224,9 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject * item is reused. This includes \c index and \c row, but also any model roles. - \note Avoid storing any state inside a delegate. If you do, reset it - manually on receiving the \l ListView::reused signal. + \note \l {Avoid Storing State in Delegates}{Avoid storing any state inside + a delegate}. If you do, reset it manually on receiving the + \l ListView::reused signal. If an item has timers or animations, consider pausing them on receiving the \l ListView::pooled signal. That way you avoid using the CPU resources @@ -2257,6 +2258,23 @@ QQuickItemViewAttached *QQuickListViewPrivate::getAttachedObject(const QObject * items, at the expense of additional memory usage. \l{ListView::section}{Sections} have the same effect because they attach and elongate the section label to the first item within the section. + + \section1 Avoid Storing State in Delegates + + ListView's delegates are instantiated as needed and may be destroyed when + out of view. For an illustration of this, run the following example: + + \snippet qml/listview/stateInDelegate.qml ListView + + When an item is clicked, \c channelActivated is set to \c true. However, + because delegates can be \l {Reusing Items}{reused} and destroyed, all + state is lost when the view is moved far enough. When the delegate becomes + visible again, it will have its default, unmodified state (or, in the case + of an item that was reused, old state from a previous item). + + To avoid this, state should be stored in the model: + + \snippet qml/listview/stateInModel.qml ListView */ QQuickListView::QQuickListView(QQuickItem *parent) : QQuickItemView(*(new QQuickListViewPrivate), parent) |
