Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QAbstractItemModel::endInsertRows message in terminal



  • i have implemented incremental loading for tree view. when a new batch is being fetched, i get the following message in terminal, and the rest of node children do not load:
    QAbstractItemModel::endInsertRows: Invalid index ( 123 , 0 ) in model QAbstractItemModel(0xwhatever)
    here are relevant functions from tree model:

    bool TreeModel::canFetchMore(const QModelIndex &parent) const
    {
    	if (!parent.isValid())
    	{
    		// return whether mode data is available
    		return m_pRootNode->childCount() < m_pRootNode->actualChildCount();
    	}
    
    	// get the node pointer
    	auto node = static_cast<TreeNode *>(parent.internalPointer());
    	return node->childCount() < node->actualChildCount();
    }
    
    void TreeModel::fetchMore(const QModelIndex &parentIdx)
    {
    	// get the node pointer
    	auto node = !parentIdx.isValid()
    		? m_pRootNode.get()
    		: static_cast<TreeNode *>(parentIdx.internalPointer());
    	if (!node) return;
    
    	// get the number of items to fetch
    	const auto nChildCount = node->childCount();
    	int itemsToFetch = qMin(node->childBatchCount(), node->actualChildCount() - nChildCount);
    	if (itemsToFetch <= 0) return;
    
    	// fetch the data from the node
    	beginInsertRows(parent(parentIdx), nChildCount, nChildCount + itemsToFetch - 1);
    	node->fetchItems(itemsToFetch);
    	endInsertRows();
    }
    
    bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    	if (!index.isValid())
    		return false;
    
    	// get the node pointer
    	auto node = static_cast<TreeNode *>(index.internalPointer());
    
    	bool bUpdated = true;
    	if (role == Qt::DisplayRole)
    	{
    		QList<QVariant> data;
    		data << value;
    		node->setColumnsData(data);
    	}
    	else if (role == Qt::CheckStateRole)
    	{
    		bUpdated = node->setProperty(index.column(), value);
    	}
    	else
    		bUpdated = false;
    
    	// emit the dataChanged() signal
    	if (bUpdated)
    	{
    		auto parentIndex = parent(index);
    		auto topLeftIndex = this->index(0, 0, parentIndex);
    		auto bottomRightIndex = this->index(
    			rowCount(parentIndex) - 1, columnCount(parentIndex) - 1, parentIndex);
    		emit dataChanged(topLeftIndex, bottomRightIndex);
    	}
    
    	return bUpdated;
    }
    
    void TreeModel::insertChild(TreeNode *parent, TreeNode *child, int row /* = -1 */)
    {
    	// get the parent node's model index
    	auto parentIndex = index(parent);
    
    	// adjust row if necessary
    	if (row == -1)
    		row = parent->childCount();
    
    	// let the model know we're making modifications
    	beginInsertRows(parentIndex, row, row);
    	parent->addChild(child, row);
    	endInsertRows();
    
    	// update the model
    	updateModel();
    }
    

    and from node:

    void TreeNode::fetchItems(int itemsToFetch)
    {
    	QSqlQuery sqlQuery(QSqlDatabase::database(getPath()));
    	sqlQuery.prepare(sQueryString).arg(itemsToFetch/* limit */).arg(childCount()/* offset */));
    
    	sqlQuery.bindValue(key, value);
    	if (!sqlQuery.exec()) return;
    
    	while (sqlQuery.next())
    	{
    		// create a node
    		addChild(new ChildNode(sqlQuery.value(0).toString(), this));
    	}
    }
    

    the node is populated with only 60 items (20 is the batch fetch count), and the number of total items is 129, but the error reports 123.


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but are you sure that you are getting as much data as you think from the database ?



  • i executed the query on the database and yes, i do get the 129 results.
    i don't get why it's reporting 123, when i only have 60 child nodes currently


  • Lifetime Qt Champion

    Just add some debug output to see what really happens / how often the stuff is called.



  • @Christian-Ehrlicher
    i did. found out after inserting 60th child node from fetchMore, endInsertRows prints the message.

    i looked at implementation of rowsInserted but i don't see how it could get from 60 to 123.



  • EDIT: i found this issue, beginInsertRows should take parent index, not parent of parent.

    i found more details on the issue.
    so i have two level tree view:

    a
    |_a1
    |_a2
    |_...
    b
    |_b2
    

    the problem occurs when i expand a first level node, e.g. a, and i get the message when the expanded node happens to be near the bottom.
    when i moved the same node near top, there's no message in terminal.
    so i guess the 123 i'm getting actually refers to first level item population, and not for expanded node.
    but see, it says ( 123 , 0 ) i.e. first column, so why is it happening when i expand the node?
    seems it is trying to insert expanded node's children as first level items, but first level items (rowCount()) are less than 123


Log in to reply