How to get list of visible QModelIndex in QAbstractItemView

旧城冷巷雨未停 提交于 2019-12-23 09:43:12

问题


Is there any way to get a list of currently visible items in QAbstractItemView? And, if it possible, to receive any notifications about changing of this list.

Upd: I'm asking exactly about QAbstractItemView or QTreeView with non-plain structure, not QTableView.

Upd2: I'm implementing tree view model with checkboxes. I want next behavior (same for checking/uncheking):

  • If one of checkbox is checked - then all childs must be checked
  • If all child checkboxes are checked - then parent check box should be checked too. And same for parent of parent, and so on...

Check state are monitored/modified by external data source, so I need a mechanism to update all changed children/parents. dataChanged signal is not enough for me because it is very expansive to build a list of all changed QModelIndex for updating. And it is not necessary at all, because all fresh data will be picked from QAbstractItemModel::data.

I found next dirty hack to update all items: emit dataChanged( QModelIndex(), QModelIndex() ); but it's undocumented for invalid indexes.

So, I need a way to force all visible items redraw they content with fresh data.


回答1:


You can get the topleft and bottom right cell by calling:

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

To get notification of change, reimplement the virtual function of qabstractscrollarea

scrollContentsBy

This function is called when the view port is scrolled. call QTableView::scrollContentsBy and then do whatever you need to.




回答2:


For QTreeView, the list of visible items can be traversed like this:

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



回答3:


I think that there are no cases where list of visible items is requred. In case of correct model implementation all items are updated automatically. Hard part of implementation - force children and parents to update. I wrote following code:

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



回答4:


i always update whole QAbstractTableModel with:

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


来源:https://stackoverflow.com/questions/15817429/how-to-get-list-of-visible-qmodelindex-in-qabstractitemview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!