Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-73733

Changes in QQmlListProperty used by DelegateModel used by ListView causes Segmentation Fault

    XMLWordPrintable

Details

    • Linux/X11
    • dbc811e164019b5f9ce371cb7b49d695644f6a90 (qt/qtdeclarative/5.12)

    Description

      In the following example, a delegate model uses a QQmlListProperty as a source model. The DelegateModel is used by a ListView. In this case, a change in the QQmlListProperty leads to a Segmentation Fault during the call of the the following line:

      // qqmldelegatemodel.cpp line 592
      QQmlDelegateModelItem *cacheItem = QQmlDelegateModelItem::dataForObject(object);
      
      

      The error does not occur when list view does not use the delegate model or if the DelegateModel does not use the underlying QQmlListProperty.

      Also, by avoiding the DelegateModel all together and having the ListView accessing the QQmlListProperty model directly, also does not crash.

      Down here there is the QML part of the example, in the attached ZIP file, you can find the whole project and additionally the backtrace caused by the Segmentation Fault.

      The QQmlListProperty model of RandomObjectsProvider contains a very simple elements of a QObjects derivative with random content.

       

      The changes in the model are caused by the objectsProvider.createNewElements() call. This method is triggered every 300ms

      // QML is shaped as follows
      import QtQuick.Window 2.2
      import QtQuick 2.6
      import QtQuick.Controls 2.0
      import QtQuick.Layouts 1.3
      import QtQml.Models 2.11
      import example 1.0
      Window {
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
          ListView {
              anchors.fill: parent
              model: delegateModel
          }
          DelegateModel {
              id: delegateModel
              model: objectsProvider.randomObjects
              delegate: delegate
              filterOnGroup: "visible"
              groups: [
                  DelegateModelGroup {
                      id: visibleGroup
                      name: "visible"
                      includeByDefault: false
                  }
              ]        items.onChanged: {
                  Qt.callLater(update)
                  // very similar backtrace with `update();`
              }
              function update() {
                  if(items.count>0)
                      items.addGroups(0, items.count, ["visible"]);
              }
          }
          Component {
              id: delegate
              Rectangle {
                  anchors.left: parent.left
                  anchors.right: parent.right
                  height: 30
                  Text {
                      text: "Data: " + (!modelData ? name : modelData.name)
                  }
              }
          }
          Timer {
              id: changeModelTimer
              property int count: 0
              interval: 300
              onTriggered: {
                  count++;
                  console.log("Round", count);
                  objectsProvider.createNewElements();
                  console.log("Number of elements",
                      objectsProvider.count());
                  if(count>=100) {
                      Qt.quit()
                  }
              }
              repeat: true
          }
          Component.onCompleted: {
              objectsProvider.createNewElements();
              changeModelTimer.start();
          }
          RandomObjectsProvider {
              id: objectsProvider
          }
      }
      

      Attachments

        Activity

          People

            ulherman Ulf Hermann
            robert_most Willy
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: