QAbstractItemModel :: index(row,column,parent)是否应该检查无效输入?

Har*_*vey 5 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();
}
Run Code Online (Sandbox Code Playgroud)

Har*_*vey 5

[如果有人有更好的答案,我会很乐意接受。]

查看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();
}
Run Code Online (Sandbox Code Playgroud)

似乎我也不知道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);
}
Run Code Online (Sandbox Code Playgroud)

为此,我不确定为什么文档会在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); }
Run Code Online (Sandbox Code Playgroud)


Mar*_*ngs 5

[我有一个更好的答案。:-)]

虽然我只是重复KDAB 的 Giuseppe D'Angelo对此的说法......

您必须区分无效和格式错误 QModelIndex:

关于无效索引(来自Qt 模型/视图编程指南中的导航和模型索引创建):

QAbstractItemModel::parent():提供与任何给定子项的父项相对应的模型索引。如果指定的模型索引对应于模型中的顶级项,或者模型中没有有效的父项,则该函数必须返回使用空构造函数创建的无效模型索引QModelIndex()。

这就解释了index.isValid():
有效索引指的是现有项,无效索引指的是所有项的根。

Giuseppe D'Angelo首先指出,无效索引(.isValid()返回)仍然是等false函数的有效输入rowCount()。hasChildren()

但 aQModelIndex也可能是格式错误的。它可以具有不存在的行或列索引,甚至可以来自不同的模型。并且QModelIndex::isValid() 不检查这一点。

朱塞佩·德安吉洛 说:

我个人对这个问题保持着相当强烈的观点:传递这样的索引是违反API契约的。永远不应该假设模型能够处理非法索引。换句话说,在我(不那么谦虚)看来,QAbstractItemModel API 的契约很窄。

但由于所有程序员都会犯错误(TM),它有助于调试过程来检查索引是否格式良好。为此,Giuseppe D'Angelo 引入QAbstractItemModel::checkIndex()了 Qt 5.11。

如果您仍在使用较低的 Qt 版本,您可以简单地自己编写该函数。