Как получить список видимых QModelIndex в QAbstractItemView

Есть ли способ получить список видимых в данный момент предметов в QAbstractItemView? И, если это возможно, получать любые уведомления об изменении этого списка.

Upd: я спрашиваю точно о QAbstractItemView или же QTreeView с непрозрачной структурой, не QTableView,

Upd2: я реализую модель представления дерева с флажками. Я хочу следующее поведение (то же самое для проверки / снятия флажка):

  • Если один из флажков установлен, то должны быть отмечены все дочерние элементы.
  • Если все дочерние флажки отмечены, то также должен быть установлен родительский флажок. И то же самое для родителя родителя, и так далее...

Проверка состояния отслеживается / изменяется внешним источником данных, поэтому мне нужен механизм для обновления всех измененных детей / родителей. dataChanged мне не хватает сигнала, потому что очень сложно построить список всех измененных QModelIndex для обновления. И это вовсе не обязательно, потому что все свежие данные будут выбраны из QAbstractItemModel::data,

Я нашел следующий грязный хак, чтобы обновить все элементы: emit dataChanged( QModelIndex(), QModelIndex() ); но это недокументировано для недопустимых индексов.

Итак, мне нужен способ заставить все видимые элементы перерисовывать их содержимое свежими данными.

5 ответов

Решение

Я думаю, что нет никаких случаев, когда список видимых элементов требуется. При правильной реализации модели все элементы обновляются автоматически. Сложная часть реализации - заставлять детей и родителей обновляться. Я написал следующий код:

bool TreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
case Qt::CheckStateRole:
        {
            TreeItemList updateRangeList;  // Filled with items, in which all childred must be updated
            TreeItemList updateSingleList; // Filled with items, which must be updated
            item->setCheckState( value.toBool(), updateRangeList, updateSingleList ); // All magic there
            foreach ( TreeAbstractItem *i, updateRangeList )
            {
                const int nRows = i->rowCount();
                QModelIndex topLeft = indexForItem( i->m_childs[0] );
                QModelIndex bottomRight = indexForItem( i->m_childs[nRows - 1] );
                emit dataChanged( topLeft, bottomRight );
            }
            foreach ( TreeAbstractItem *i, updateSingleList )
            {
                QModelIndex updateIndex = indexForItem( i );
                emit dataChanged( updateIndex, updateIndex );
            }
        }

Вы можете получить верхнюю и нижнюю правую ячейку, вызвав:

tableview->indexAt(tableview->rect().topLeft())
tableview->indexAt(tableview->rect().bottomRight())

Чтобы получить уведомление об изменении, переопределите виртуальную функцию qabstractscrollarea.

scrollContentsBy

Эта функция вызывается при прокрутке порта просмотра. вызовите QTableView::scrollContentsBy и затем делайте все, что вам нужно.

За QTreeViewсписок видимых элементов можно просмотреть следующим образом:

QTreeView& tv (yourTreeView);

// Get model index for first visible item
QModelIndex modelIndex = tv.indexAt(tv.rect().topLeft());

while (modelIndex.isValid())
{
    // do something with the item indexed by modelIndex
    ...
    // This navigates to the next visible item
    modelIndex = tv.indexBelow(modelIndex);
}

Способ 1

      i, j = table.indexAt(table.rect().topLeft()).row(), table.indexAt(table.rect().bottomLeft()).row() - 1

Способ 2

      i, j = table.rowAt(0), table.rowAt(table.height()) - 1

Я всегда обновляю всю QAbstractTableModel:

emit dataChanged(index(0, 0), index(rowCount(), columnCount()-1)); // update whole view
Другие вопросы по тегам