从 QTreeView 中的 QModelIndex 获取平面行索引

Posted

技术标签:

【中文标题】从 QTreeView 中的 QModelIndex 获取平面行索引【英文标题】:Get flat row index from QModelIndex in QTreeView 【发布时间】:2018-12-07 10:04:02 【问题描述】:

我有一个分层的 Qtreeview 结构视图和模型,其中包含多个带有子行的行,方式如下:

                                Index(index.row())        Desired flat index

- Row1                           0                               0
  - child1                       0                               1               
  - child2                       1                               2               
  - child3                       2                               3               
    - child11                    0                               4                                        
    - child22                    1                               5                  
      - child 221                0                               6                     
    - child33                    2                               7                  
      - child 31                 0                               8                     
      - child 32                 1                               9                    
  - child4                       3                               10                                      
    - child41                    0                               11                  
    - child42                    1                               12                  
- Row2                           2                               13               
  - child1                       0                               14               
    - child 11                   0                               15                   
    - child 12                   1                               16                  
      - child 121                0                               17                     
  - child2                       1                               18               
  - child3                       2                               19                   
  - child4                       3                               20               
    - child41                    0                               21                  
    - child42                    1                               22                  

每个索引的 index.row() 都会给出与其所在的父级相关的行号。有没有什么快速的方法可以在 Qt 本身的图中找到所需的平面索引?上面的示例显示了一个非常简单的层次结构。它非常复杂,即有几个层次结构和行数。

【问题讨论】:

看看KDescendantsProxyModel KDE API 中用于展平树模型的代理类。 【参考方案1】:

您可以使用以下代码获取与给定模型索引对应的平面索引:

// Returns the total number of children (and grand children).
static int childCount(const QModelIndex &index)

  auto model = index.model();
  int count = model->rowCount(index);
  for (int r = 0; r < count; ++r) 
    count += childCount(index.child(r, 0));
  
  return count;


// Returns the flat index for the given model index (hierarchical).
static int flatIndex(const QModelIndex &index)

  if (!index.isValid()) 
    return -1;
  

  int result = index.row() + 1;
  auto parent = index.parent();

  // Get the number of all items above.
  for (int r = 0; r < index.row(); ++r) 
    result += childCount(index.model()->index(r, 0, parent));
  

  return result + flatIndex(parent);

希望它是如何计算索引的。

【讨论】:

添加了代码。但它现在导致堆栈溢出。调试一样。请注意它是一个 UI,因此性能也是一个关键因素。由于这个函数会从 Model::data() 中调用,所以 flatIndex() 需要轻量级。 你怎么称呼它?它应该是模型的data() 函数中的一行代码。这应该只发生在单个列(在您的示例中为第三列),即if (index.column() == 2 &amp;&amp; role == Qt::DisplayRole) return flatIndex(index);。但是,确实,对于非常深和大的层次结构,它可能会导致堆栈溢出。 是的,我只为第 2 列和显示角色这样做。但是,正如您正确地说的那样,层次结构很大,它会引起一些问题。 考虑性能方面,您可能会扩展建议的代码并在模型中缓存已计算的平面索引。 IE。一旦计算完毕,除非您的模型数据发生更改(添加/删除项目),否则您不会再次计算它。

以上是关于从 QTreeView 中的 QModelIndex 获取平面行索引的主要内容,如果未能解决你的问题,请参考以下文章

QTableWidget 作为 QTreeView 中的子级

拖放到 QTreeView 中的 QStandardItemModel 不起作用

从 ModelIndex 扩展 QTreeView 项目 [重复]

如何使用 QAbstractItemModel 从 QTreeView 中删除行?

如何从 QStyle 获取 QTreeView 的标识宽度

禁用(灰显)QTreeView 中的某些行