2
votes

I'm trying to unittest my implementation of QAbstractTableModel. I have implemented rowCount(), columnCount() and data() methods.

After instantiating my model, no matter how many nestings deep, the parent index is always invalid:

parent = model->index(0, 0);
i = model->index(0, 0, parent); // i.parent().IsValid() == false!

Now, i is valid. But i.parent() is not. Even if I do further nesting:

ancestor = model->index(0, 0);
parent = model->index(0, 0, ancestor);
i = model->index(0, 0, parent); // i.parent().IsValid() == false!

even then, i is valid but i.parent() is not.

I have unit tested the rowCount and columnCount methods and I've asserted that the model is a tree model that has one row with, nested, two rows. Also, the column count is nonzero.

Why is my parent index always invalid?

1
are you sure you are actually setting is parent? - Dillydill123
If you want to create a tree model, you need to derive fromQAbstractItemModel not QAbstractTableModel - RobbieE

1 Answers

5
votes

It's a table. It's not supposed to be a tree. Because of that, the parent will always be invalid. The QAbstractTableModel::index implementation always sets an invalid parent, and it's supposed to.

Your expectations apply to a tree model, not a table model. And they only apply to a tree model if the given parent element has children. Your test wrongly assumes that the parent it is using has children, when it has none. You can easily check that: model->hasChildren(parent) will always return false for a table. Trying to create an index with a childless parent is undefined. Ideally your model should assert on it. Thus, your test would be generally wrong for a tree too.

If you want to implement a tree, derive from QAbstractItemModel. You'll then be forced to correctly implement bool hasChildren(const QModelIndex& parent) const - that's the method that the tree view (and your tests!) should use to know whether it's valid to request an index for a given parent's child.

Generally speaking, if model.hasChildren(parent) == false then you're never supposed to call model.index(row, col, parent). In fact, your model should assert that it is so:

QModelIndex MyModel::index(int row, int col, const QModelIndex & parent) {
  Q_ASSERT(hasChildren(parent));
  Q_ASSERT(row >= 0 && row < rowCount(parent));
  Q_ASSERT(col >= 0 && col < columnCount(parent));
  void * ptr = ...; // or quintptr ptr = ...;
  return createIndex(row, col, ptr);
}