1
votes

I am trying to use a selection (QModelIndexList) to check all the selected items of a QTreeView.

I use setData with the Qt::CheckStateRole on the indexes and the data seems updated. I am emitting dataChanged signal but the tree is not redrawn (with and without the role given as argument). Is this an issue of the selection model?

It works if I do beginResetModel but my tree gets collapsed which a deal breaker.

How can I manage to get my item repainted?

Here is the method I added in my model

void MyModel::checkSelectedItems( const QModelIndexList &checkedIndexes, bool check )
{
    QVector<int> roles = QVector<int>() << Qt::CheckStateRole;
  for ( const QModelIndex &index : checkedIndexes)
  {
      setData(index, check ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
      emit dataChanged(index, index); //), roles);
  }
}

and the call to it:

myModel->checkSelectedItems( myTree->selectionModel()->selectedIndexes(), true );

After the call, the selection is grey (and not blue anymore) but still "selected". Clicking anywhere refresh the tree and correctly shows the checked items.

1
After myModel->checkSelectedItems( myTree->selectionModel()->selectedIndexes(), true ); write myTree->update();. - scopchanov
that does not seem to solve the issue, also tried to call myTree->update(index) with the modified index. - Denis Rouzaud
I am sorry! In this moment I don't have further ideas. I will check that again later. - scopchanov
no worries, it was worth a try, thanks for the hint! - Denis Rouzaud
myTree->repaint() solved the issue, but I am not sure this is the correct approach. - Denis Rouzaud

1 Answers

0
votes

The code you show works mostly fine in spite of being incorrect. Please amend the question to include a reproduction case. But yes, the code does have problems.

It is in setData's contract to emit the dataChanged signal; any code where dataChanged is emitted outside of setData indicates a broken implementation of the model. You should move the signal emission to MyModel::setData. The only other place where it'd be valid to emit dataChanged is in a slot/functor in a proxy model, but only when the slot/functor is connected to the sourceModel's dataChanged signal.

myTree->repaint() solved the issue

Invoking repaint() or update() outside of a widget's implementation is almost always an error, and indicates that the widget is either not used properly or is not implemented properly. In your case, it's the former: the model's setData is broken and doesn't emit dataChanged.

For inspiration on how such a test case might look like, see e.g. this answer. In a nutshell: aim for 100 lines or less, single file, #include <QtWidgets> at the beginning, no unnecessary code nor boilerplate. Make it sweet and simple :)