kanders-fatpot
kanders-fatpot

Reputation: 141

Qt Model within a model?

I have a Qt model which could very well be a QAbstractListModel. Each "row" represents an object I have stored in a QList. I'm displaying this in QML in a ListView. However, each object has one property that happens to be an array of strings. I would like to display this as a ListView within the delegate that displays that row. But I don't know how to expose that model (for the string array property of the object) to QML. I can't expose it through the data function since Models are QObjects, which cannot be QVariants. I thought of using QAbstractItemModel instead, but I still don't know how to get a model for my ListView. In case it matters, I'm using Qt 5.0.0 release.

Upvotes: 6

Views: 2969

Answers (1)

JuliusG
JuliusG

Reputation: 2371

You can return QVariantList from your main QAbstractListModel and this can then be assigned as a model to your internal ListView that you have in the delegate. I have added a small example that has a very simple one row model with internal model as an example.

The c++ model class:

class TestModel : public QAbstractListModel
{
  public:

  enum EventRoles {
    StringRole = Qt::UserRole + 1
  };

  TestModel()
  {
    m_roles[ StringRole] = "stringList";
    setRoleNames(m_roles);
  }

  int rowCount(const QModelIndex & = QModelIndex()) const
  {
    return 1;
  }

  QVariant data(const QModelIndex &index, int role) const
  {
    if(role == StringRole)
    {
      QVariantList list;
      list.append("string1");
      list.append("string2");
      return list;
    }
  }

  QHash<int, QByteArray> m_roles;
};

Now you can set this model to QML and use it like this:

ListView {
  anchors.fill: parent
  model: theModel //this is your main model

  delegate:
    Rectangle {
      height: 100
      width: 100
      color: "red"

      ListView {
        anchors.fill: parent
        model: stringList //the internal QVariantList
        delegate: Rectangle {
          width: 50
          height: 50
          color: "green"
          border.color: "black"
          Text {
            text: modelData //role to get data from internal model
          }
        }
      }
    }
}

Upvotes: 6

Related Questions