UncleZeiv
UncleZeiv

Reputation: 18488

How can I force Qt to call `data()` on my model?

I've got a QtTreeView and a class Foo derived from QAbstractItemModel attached to it.

In Foo::data I set the Qt::BackgroundRole for each element of the tree according to the status of some internal data.

When I receive a signal to update my internal data I would like to update the background of each item accordingly, but I can't seem to reliably make Qt call my Foo::data method.

I've tried calling update() and repaint() (on the view), to no avail. Calling reset() works but I lose all the state of the tree (e.g. expanded elements etc.). Calling setData() on each element also works but the code gets a bit awkward as I have to explicitly rebuild the tree of data displayed which is not nice.

How can I force Qt to call data() on my model?

Upvotes: 2

Views: 1667

Answers (3)

James Turner
James Turner

Reputation: 2485

You need to inform the view class your model has changed, by emitting the dataChanged signal.

Upvotes: 5

UncleZeiv
UncleZeiv

Reputation: 18488

Futher to James Turner's correct answer, here's some additional code for future reference. To signal that all data has changed, one needs to retrieve the indices of the first and the last item.

The first item is trivial:

QModelIndex FooModel::firstIndex() const
{
    return index( 0, 0 );
}

The last item is trivial as well for a single level hierarchy:

QModelIndex FooModel::lastIndex() const
{
    QModelIndex lastTopLevelIndex = index( rowCount() - 1, 0 );
    return index( rowCount( lastTopLevelIndex ) - 1, kNumColumns, lastTopLevelIndex );
}

and a bit more complex in the general case:

QModelIndex FooModel::lastIndex() const
{
    QModelIndex parent;
    QModelIndex candidate;
    QModelIndex lastIndex;
    int row = rowCount();

    while ( row > 0 )
    {
        parent = index( row - 1, 0, parent );
        candidate = index( row - 1, kNumColumns, parent );
        row = rowCount( parent );
    }

    return candidate;
}

(I'm not sure if it's important to always have the parent on the first column or not...)

Upvotes: 1

Kamil Klimek
Kamil Klimek

Reputation: 13130

Try beginResetModel() when you start to modify data and then endResetModel(), but remember that your view/model will have poor performance on each change, because whole model will be queried and painted again

Upvotes: 2

Related Questions