c++qtmodel-view-controllerqt5qtestlib

Qt Model Test, removeRows


I have a tree model with internal structure similar to Simple Tree Model Example. There is a special array-type items, for which I want to display an index. My data method looks like this:

QVariant Model::data(const QModelIndex & index, int role ) const
{
    if (!index.isValid())
        return QVariant();

    TreeNode *item = getItem(index);

    if (role == Qt::DisplayRole) {
        return item->text();
    }
    ...

    return QVariant();
}

const QString TreeNode::text() const
{
    if (array) {
        return name() + " [" + QString::number(childNumber()) + "]";
    }
    return mText;
}

I have a unit test that performs node removal, which uses Model Test. The problem occurs in the last line of this test

void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
{
    Changing c = remove.pop();
    QVERIFY( c.parent == parent );
    QVERIFY( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) );
    QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
    QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) );
}

which compares the value before removal with value after removal. In my case, since I also display indices, they don't match. For example, I had Item1 and Item2 in the model. If Item1 is removed, then Item2 becomes Item1 and the test fails.

My question is is something wrong in my model implementation? Should I handle this situation differently?


Solution

  • Data in QAbstractItemModel cannot be just silently changed. You should always emit dataChanged signal for indexes which data has changed.

    If you do this:

    " [" + QString::number(childNumber()) + "]"
    

    then you need to emit dataChanged signal each time childNumber() changed. So it would be much easier if index data could be changed only via QAbstractItemModel::setData.