对QAbstractItemModel进行子类化,我已根据需要实现了自己的index()方法。我目前检查有效输入,但我想知道这是否正确。我想知道为不存在的数据创建索引是否有效?也许在插入行或列时?
代码:
QModelIndex LicenseDataModel::index(int row, int column, const QModelIndex & /*parent*/) const
{
/// TODO: Is this necessary? Should we avoid creating invalid indexes? Or could this
/// be a bug?
if (validRowColumn(row, column))
return createIndex(row, column);
return QModelIndex();
}
答案 0 :(得分:4)
[如果有人有更好的答案,我会很乐意接受它。 ]
查看QListWidget的来源,检查输入似乎是Qt自己做的事情:
QModelIndex QListModel::index(int row, int column, const QModelIndex &parent) const
{
if (hasIndex(row, column, parent))
return createIndex(row, column, items.at(row));
return QModelIndex();
}
我似乎也不知道hasIndex()将执行validRowColumn()
方法的操作。
bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
{
if (row < 0 || column < 0)
return false;
return row < rowCount(parent) && column < columnCount(parent);
}
就此而言,当index.isValid()
更合适时,我不确定文档为何会在任何地方使用hasIndex(index.row(), index.column(), index.parent())
。然后,我确定会添加hasIndex(QModelIndex &)
方法。 hasIndex()
执行与QModelIndex::isValid()
及更多相同的检查:
inline bool isValid() const { return (r >= 0) && (c >= 0) && (m != 0); }
答案 1 :(得分:1)
[我有一个更好的答案。 :-)]
尽管我只是重复Giuseppe D'Angelo from KDAB关于此事的话...
您必须区分无效和格式错误 QModelIndex
:
关于无效索引(来自Qt的《模型/视图编程指南》中的Navigation and model index creation)
QAbstractItemModel::parent()
:提供与任何给定子项的父项相对应的模型索引。如果指定的模型索引对应于模型中的顶级项,或者模型中没有有效的父项,则该函数必须返回由空QModelIndex()
构造函数创建的无效模型索引。>
这说明了index.isValid()
的含义:
有效索引是指现有项目,无效索引是指所有项目的根。
Giuseppe D'Angelo首先指出,无效索引(.isValid()
返回false
)仍然是rowCount()
,{ {1}}等。
但是hasChildren()
也可以格式错误。它可以具有不存在的行或列索引,甚至可以来自其他模型。并且QModelIndex
不对此进行确认。
朱塞佩·德安吉洛说:
我个人对此问题持有很强的观点:传递此类索引违反了API合同。永远不应假定模型能够处理非法索引。换句话说,以我的观点(不是很谦虚),QAbstractItemModel API的合同范围很窄。
但是,由于所有程序员都会犯错误(TM),因此它有助于调试过程检查索引的格式是否正确。为此,Giuseppe D'Angelo在Qt 5.11中引入了QAbstractItemModel::checkIndex()
。
如果您仍在使用较低的Qt版本,则只需自己编写该函数即可。