I have a QTreeView
served by a QAbstractItemModel
subclass which is built over a custom tree data model. The data model is defined like this:
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
// ...
}
Everything is working perfectly, I can add, edit, move and remove rows. Now, if I try to use a QVector instead of QList, the model works as intended when initially populating it with the data, but when I try to add a new row, I experience weird behavior: the row is being added to the model and shown in the view normally, but when I try to expand\collapse neighbouring nodes, the program crashes. I have located the source of the crash, the findRow
method, which is used in the required QAbstractItemModel
's parent
method:
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);
}
When I try to expand\collapse a node, searchList.indexOf(*targetNode);
crashes the program without any feedback. I wanted to dig deeper and rewrote the search to get some more info about what's happenening and apparently Q_ASSERT(position != searchList.end());
this condition fails.
Now, I've read some info about differences between QVector and QList, including this very helpful discussion. I do understand the main differences between both and get the felling that the main cause is some quirk in the memory management, but I still have hard time figuring out why this happens.
Can someone please explain?