我正在尝试对QAbstractTableModel的实现进行单元测试。我已经实现了rowCount(),columnCount()和data()方法。
实例化我的模型后,无论深度嵌套多少,父索引始终无效:
parent = model->index(0, 0);
i = model->index(0, 0, parent); // i.parent().IsValid() == false!
现在,我有效。但是i.parent()不是。 即使我做进一步的嵌套:
ancestor = model->index(0, 0);
parent = model->index(0, 0, ancestor);
i = model->index(0, 0, parent); // i.parent().IsValid() == false!
即便如此,我仍然有效,但i.parent()不是。
我已经对rowCount和columnCount方法进行了单元测试,并且我断言该模型是一个树模型,其中一行有嵌套的两行。此外,列数不为零。
为什么我的父索引始终无效?
答案 0 :(得分:4)
这是一张桌子。它不应该是一棵树。因此,父母将永远无效。 QAbstractTableModel::index
实现总是设置一个无效的父级,它应该是。
您的期望适用于树模型,而不适用于表模型。并且如果给定的父元素具有子元素,它们仅适用于树模型。您的测试错误地假定它正在使用的父项具有子项,而它没有子项。您可以轻松检查:model->hasChildren(parent)
将始终返回false
表。尝试使用无子窗口父级创建索引是未定义的。理想情况下,您的模型应该断言。因此,对于树来说,您的测试通常也是错误的。
如果要实现树,请从QAbstractItemModel
派生。然后,您将被迫正确实现bool hasChildren(const QModelIndex& parent) const
- 这是树视图(和您的测试!)应该用来知道为给定父项的子项请求索引是否有效的方法。
一般来说,如果model.hasChildren(parent) == false
,那么您永远不应该致电model.index(row, col, parent)
。事实上,你的模型应该声明它是这样的:
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);
}