Qt QBStractItemModel::index(行、列、父级)是否应检查无效输入?

Qt QBStractItemModel::index(行、列、父级)是否应检查无效输入?,qt,Qt,作为QAbstractItemModel的子类,我根据需要实现了自己的index()方法。我目前正在检查有效的输入,但我想知道这是否正确。我想知道为一段不存在的数据创建索引是否有效?可能是在插入行或列时 代码: [如果有人有更好的答案,我很乐意接受。] 从源代码来看,检查输入似乎是Qt本身的工作: QModelIndex QListModel::index(int row, int column, const QModelIndex &parent) const { if (ha

作为QAbstractItemModel的子类,我根据需要实现了自己的index()方法。我目前正在检查有效的输入,但我想知道这是否正确。我想知道为一段不存在的数据创建索引是否有效?可能是在插入行或列时

代码:


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

从源代码来看,检查输入似乎是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();
}
似乎我也不知道我的
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);
}

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

虽然我只是重复关于这个的话

必须区分无效的格式错误的
QModelIndex

关于无效索引(来自Qt的模型/视图编程指南):

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

这解释了
index.isValid()的含义。

有效索引指的是现有项,无效索引指的是所有项的根。

首先要注意的是,一个无效的索引(带有返回的
false
)仍然是像
rowCount()
haschilds()
等函数的有效输入

但是
QModelIndex
也可能是格式不正确的。它可以具有不存在的行或列索引,甚至可以来自不同的模型。并且
QModelIndex::isValid()
不会检查该值

朱塞佩·德安吉洛说:

我个人在这个问题上持有相当强烈的观点:通过这样的指数违反了API合同。决不能假设模型能够处理非法索引。换句话说,在我看来(不是那么谦虚),QabstracteModel API有一个狭窄的契约

但是,由于所有程序员都会犯错误(TM),因此检查索引的格式是否正确有助于调试过程。为此,Giuseppe D'Angelo将其引入Qt5.11


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

例如,当您单击没有视图项的区域时,索引可能无效。在这种情况下,正如我正确回忆的那样,行和/或列值为负值,您需要返回无效索引:
returnqmodelindex()我想我应该看看Qt在QListWidget中是如何实现的。实际上,默认的QModelIndex()对象是无效的,它表示根节点。因此,如果根下有子级,hasIndex(0,0,QModelIndex())将返回true。
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);
}
inline bool isValid() const { return (r >= 0) && (c >= 0) && (m != 0); }