如何在QAbstractItemView中获取可见QModelIndex的列表

时间:2013-04-04 17:07:50

标签: qt model-view-controller qmodelindex qabstractitemview

有没有办法在QAbstractItemView中获取当前可见项目的列表?并且,如果可能,接收有关更改此列表的任何通知。

UPD: 我要问的是具有非普通结构的QAbstractItemViewQTreeView,而不是QTableView

UPD2: 我正在使用复选框实现树视图模型。我想要下一个行为(检查/取消检查相同):

  • 如果选中其中一个复选框 - 则必须检查所有子项
  • 如果选中所有子复选框 - 则也应检查父复选框。父母的父母也一样,等等......

检查状态由外部数据源监控/修改,因此我需要一种机制来更新所有已更改的子/父。 dataChanged信号对我来说是不够的,因为构建所有已更改QModelIndex的列表以进行更新非常容易。并且根本不需要,因为所有新数据都将从QAbstractItemModel::data中选取。

我发现下一个脏黑客更新了所有项目:emit dataChanged( QModelIndex(), QModelIndex() );但是它没有记录无效索引。

所以,我需要一种方法来强制所有可见的项目用新数据重新绘制内容。

4 个答案:

答案 0 :(得分:10)

您可以致电:

获取topleft和right right单元格
tableview->indexAt(tableview->rect().topLeft())
tableview->indexAt(tableview->rect().bottomRight())

要获得更改通知,请重新实现qabstractscrollarea的虚函数

scrollContentsBy

滚动视口时调用此函数。 调用QTableView :: scrollContentsBy然后做你需要的任何事情。

答案 1 :(得分:4)

对于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);
}

答案 2 :(得分:0)

我认为不存在需要列出可见项目的情况。如果模型实施正确,所有项目都会自动更新。 实施的艰难部分 - 强迫孩子和父母更新。我写了以下代码:

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 );
            }
        }

答案 3 :(得分:0)

我总是用以下内容更新整个QAbstractTableModel:

emit dataChanged(index(0, 0), index(rowCount(), columnCount()-1)); // update whole view