QAbstractItemModel :: index(行,列,父)是否应检查无效输入?

时间:2013-12-11 21:50:46

标签: qt

对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();
}

2 个答案:

答案 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版本,则只需自己编写该函数即可。