我有一个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
即在 required 的方法中使用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 之间差异的信息,包括这个非常有用的讨论。我确实了解两者之间的主要区别,并认为主要原因是内存管理中的一些怪癖,但我仍然很难弄清楚为什么会发生这种情况。
有人可以解释一下吗?