0

As in this Question I have a QTreeView with 2 Columns of checkable entries. Now I want to check/uncheck all children/subitems of an item recursively.

What I tried ist this:

      bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (role != Qt::EditRole && role != Qt::CheckStateRole)
            return false;
    
        TreeItem *item = getItem(index);
        bool result;
        if ( role == Qt::CheckStateRole && isBooleanColumn( index ) )
        {
            Qt::CheckState eChecked = static_cast< Qt::CheckState >( value.toInt() );
            bool bNewValue = eChecked == Qt::Checked;
            result = item->setData( index.column(), bNewValue );
            
            if (item->childCount() > 0) {
              for (int r = 0; r < item->childCount(); r++)
              {
                /*QModelIndex mi;
                if (this->hasIndex(r, index.column(), index))
                  mi = this->index(r, index.column(), index);
                else
                  mi = this->createIndex(r, index.column(), item->child(r));
                this->setData(mi, bNewValue, role);
                */

// with this code I can set the children in the first level:
                bool x = item->child(r)->setData(index.column(), bNewValue);
                if (x) {
                  QModelIndex mi=this->createIndex(r, index.column(), item->child(r));
                  emit dataChanged(mi, mi, { Qt::DisplayRole, Qt::EditRole });
                }
              }
            }
        }
        else
        {
            result= item->setData(index.column(), value);
        }
        
        if (result)
            emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
    
        return result;
    }

But I'm not able to set the values recursively, because there is needed a QModelIndex. By trying to create one I get r=-1 and c=-1, its not valid.

What is wrong with my logic?

Frau Schmidt
  • 152
  • 11

1 Answers1

1

Maybe someone is interested in my solution:

    bool TreeModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
  if (role != Qt::EditRole && role != Qt::CheckStateRole)
    return false;

  TreeItem* item = getItem(index);
  bool result;
  if (role == Qt::CheckStateRole && isBooleanColumn(index))
  {
    Qt::CheckState eChecked = static_cast<Qt::CheckState>(value.toInt());
    bool bNewValue = eChecked == Qt::Checked;
    result = item->setData(index.column(), bNewValue);

    if (item->childCount() > 0) {
      for (int r = 0; r < item->childCount(); r++)
      {
        QModelIndex mi = this->createIndex(r, index.column(), item->child(r));
        this->setData(mi, value, role);
      }
    }
  }
  else
  {
    result = item->setData(index.column(), value);
  }

  if (result)
    emit dataChanged(index, index, { Qt::DisplayRole, Qt::EditRole });

  return result;
}

I have to create a new QModelIndex for each child node and then give it in setData the value as QVariant and not as Boolean (bNewValue). Otherwise bNewValue comes as partiallyChecked (don't know why) which inverts the result.

Frau Schmidt
  • 152
  • 11