Qt World Summit: Submit your Presentation

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);
    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;
    	else if (role == Qt::CheckStateRole)
    		bUpdated = node->setProperty(index.column(), value);
    		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);
    	// update the model

    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


    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:


    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