Solved Trouble with CheckDelegate
-
Hello. I am using CheckDelegate in a ListView. Next, I want to use the values of each delegate in C ++ code. The component is created correctly, but in the C ++ part I see only 1 object from the delegate, and not 20 as I expect. If i use Item rather than CheckDelegate, everything works as it should. But here it is a matter of principle to understand what is the matter and what needs to be done. Here is the code:
import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.12 ApplicationWindow { id: app visible: true width: 640 height: 480 title: qsTr("BPV") ColumnLayout { id: columnLayout anchors.fill: parent ScrollView { id: scrollView Layout.fillWidth: true Layout.fillHeight: true clip: true ListView { id: listView objectName: "listView" signal sendCodogramm() model: 20 delegate: CheckDelegate { width: parent.width - 15 text: index objectName: "delegate" } } } Button { id: button text: qsTr("Button") Layout.fillWidth: true onClicked: { console.log(scrollView.contentHeight) console.log(listView.contentItem) console.log(listView.height) listView.sendCodogramm() } } } }
And C++ part:
QList<QObject *> lst = engine.rootObjects(); QObject *mwind = lst[0]; QObject *listView = mwind->findChild<QObject *>("listView"); QQuickItem *listContent = qvariant_cast<QQuickItem *>(listView->property("contentItem")); QList<QQuickItem *> contentItem = listContent->childItems(); for (auto childItem: contentItem ) { if (childItem->objectName() == "delegate") qDebug() << childItem->property("text").toInt() << childItem->property("checked").toBool(); }
Also noticed that if I put cacheBuffer: contentHeight
then all 20 elements are output, but QML writes an error related to looping. If i write height: contentHeight, it displays up to 16, and the program crashes -
delegate
property is an Component. It is not a list of created objects. Component instantiated them by demand. Moreover ListView can not hold all delegates at the same time. They are destroyed by ListView when they comes out of viewport. You should instead use models properly, QAbstractListModel for example.
Of cource you can- access
contentItem
property and its children, but it is items only dysplayed now by ListView; - use
Column
+Repeater
for small models, otherwise it can take too much memory; - probably you can access to a
ListModel
, but i never tested this.
- access
-
@IntruderExcluder You are absolutely right. I know about ListView and Delegate, and the objects that a ListView creates on the basis of Delegate become "content item". Just I take the objects from the "content item", but there is only one instance of Delegate, although at least those that are in scope should be.
-
I solved the problem. I add this, and all work fine:
ListView { id: listView objectName: "listView" cacheBuffer: listView.count*30 delegate: CheckDelegate { height: 30 width: parent.width - 15 text: index checked: index > 10 ? true : false objectName: "delegate" } model: 20 }
This line is a key: cacheBuffer: listView.count*30. If i wrote cacheBuffer: <const value>, i had a my problem in topic.