我有一个由QTreeView
子类提供服务的QAbstractItemModel
,它是在自定义树数据模型上构建的。数据模型的定义如下:
struct InventoryNode
{
// ctors, operator definitions
// ...
InventoryItem inventoryItem; // node data
QList<InventoryNode> children; // child nodes
InventoryNode *parent = nullptr; // parent pointer
};
class InventoryModel : public QAbstractItemModel
{
Q_OBJECT
public:
struct InventoryNode;
QList<InventoryNode> _nodes; // root nodes
// required model methods
// ...
}
一切都很完美,我可以添加,编辑,移动和删除行。现在,如果我尝试使用QVector而不是QList,那么在最初使用数据填充时,模型会按预期工作,但是当我尝试添加新行时,我会遇到奇怪的行为:行被添加到模型中通常在视图中显示,但是当我尝试展开\折叠相邻节点时,程序崩溃了。我找到了崩溃的来源findRow
方法,该方法在所需的QAbstractItemModel
parent
方法中使用:
QModelIndex InventoryModel::parent(const QModelIndex &index) const
{
if (!index.isValid()) {
return QModelIndex();
}
InventoryNode *currentNode = static_cast<InventoryNode *>(index.internalPointer());
InventoryNode* parentNode = currentNode->parent;
if (parentNode != nullptr) {
return createIndex(findRow(parentNode), BranchColumn, parentNode);
}
else {
return QModelIndex();
}
}
int InventoryModel::findRow(const InventoryNode *targetNode) const
{
const InventoryNodeList searchList = targetNode->parent != nullptr ? targetNode->siblings() : _nodes;
// return searchList.indexOf(*targetNode);
InventoryNodeList::const_iterator position = std::find(searchList.begin(), searchList.end(), *targetNode);
// Q_ASSERT(position != searchList.end());
return std::distance(searchList.begin(), position);
}
当我尝试展开\折叠节点时,searchList.indexOf(*targetNode);
会在没有任何反馈的情况下崩溃程序。我想深入挖掘并重新编写搜索,以获得更多关于发生了什么的信息,显然Q_ASSERT(position != searchList.end());
这种情况失败了。
现在,我已经阅读了有关QVector和QList之间差异的一些信息,包括this非常有用的讨论。我确实理解两者之间的主要区别并且得到了主要原因是内存管理中的一些怪癖,但我仍然很难搞清楚为什么会发生这种情况。
有人可以解释一下吗?