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

[REG 6.5.3 -> 6.8.3] ListModel set() on existing index fails if setting data retrieved from C++ QVariantMap containing a QVariantList role

    XMLWordPrintable

Details

    Description

      Hello,

      While porting my app from 6.5.3 to 6.8.3, I found out that set() function of QML ListModel no longer works when we pass a QVariantList of QVariantMaps to it, if previous item already exists, and produces the following warning:

      <Unknown File>: Can't assign to existing role 'b' of different type [VariantMap -> List]
      

      This used to work previously, since when a property of the object passed to set() is an array, it's supposed to create an internal ListModel for it and apply the roles of the inner object to it.

      Pure QML/JS works properly, this seems to affect only C++ code:

      Working:

      Item {
          id: testItem
      
          ListModel {
              id: testModel
          }
      
          function getSomeData(count) {
              var list = [];
              for (var i = 0; i < count; ++i)
                  list.push({ r: i, s: String(i) });
              return { a: 2, b: list };
          }
      
          Component.onCompleted: function() {
              testModel.set(0, getSomeData(10));
              testModel.set(0, getSomeData(10));
      
              console.log(testModel.count);
              console.log(testModel.get(0)["b"].get(1)["r"]);
          }
      }
      

      Then if we instead get the data from a C++ class exposed to QML, that produces the same but returning a QVariantList of QVariantMaps, this no longer works:

      QVariantMap getSomeData(int count)
      {
          QVariantList list;
      
          for (int i = 0; i < count; ++i)
          {
              QVariantMap item;
              item[QLatin1String("r")] = i;
              item[QLatin1String("s")] = QString::number(i);
              list.append(item);
          }
      
          QVariantMap data;
          data[QLatin1String("a")] = 2;
          data[QLatin1String("b")] = list;
          return data;
      }
      

      There seem to have been related changes around setArrayLike(), maybe with new "if" statements, it now goes to setArrayLike() while it would earlier go through others ifs, I am not sure.

      Passing a QVariantMap without list inside still works properly.

      As a workaround, we can do JSON.parse(JSON.stringify(data)) but this is not great for performance.

      Feel free to ask for more details if needed,

      Thank you,
      Louis

      Attachments

        For Gerrit Dashboard: QTBUG-136581
        # Subject Branch Project Status CR V

        Activity

          People

            ulherman Ulf Hermann
            amnell Louis du Verdier
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There is 1 open Gerrit change