Как получить список видимых 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