首页 > 解决方案 > 没有 layoutChanged,QTreeView 新行不可见

问题描述

我已经基于此示例实现了分层 qtreeview:http: //doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

我还使用 QSortFilterProxyModel 和模型进行过滤

我使用 addentry 函数构建树视图,每当模块接收到新数据时都会调用该函数。函数如下:

void cTreeModel::addEntry(QModelIndex& sParentIndex, const tDataID id, cAbstractTreeItem *pParentItem)
        {

           switch (pParentItem->type()) {

           case cAbstractTreeItem::TROOT:
           {
              cAbstractTreeItem* pAItem = pParentItem->hasEntry(id);
              QModelIndex sAItemIndex;
              if(nullptr == pAItem)
              {
                 beginInsertRows(QModelIndex(), getRootItem()->childCount(), getRootItem()->childCount());
                 pAItem = new cATreeItem(id, pParentItem); //essentially m_pParentItem->appendChild(this);
                 endInsertRows();
              }
              else
              {
                 pAItem->updateData();
              }
              sAItemIndex = index(pAItem->row());
              addEntry(sAItemIndex, id, pAItem);
              break;
           }

           case cAbstractTreeItem::TA
           {
              cAbstractTreeItem* pB = pParentItem->hasEntry(id);
              if(nullptr == pB)
              {
                 beginInsertRows(sParentIndex, pParentItem->childCount(), pParentItem->childCount());
                 pB = new cBTreeItem(id, pParentItem); //essentially m_pParentItem->appendChild(this);
                 endInsertRows();
              }
              else
              {
                 pB->updateData();
              }
              QModelIndex sBItemIndex = index(pB->row(), 1, sParentIndex);
              addEntry(sBItemIndex, id, pB);
              break;
           }

           case cAbstractTreeItem::TB:
           {
              cAbstractTreeItem* pTC = pParentItem->hasEntry(id);
              if(nullptr == pTC)
              {
                 beginInsertRows(sParentIndex, pParentItem->childCount(), pParentItem->childCount());
                 pTC = new cCTreeItem(id, pParentItem); //essentially m_pParentItem->appendChild(this);
                 endInsertRows();
              }
              else
              {
                 pTC->updateData();
              }
              QModelIndex sCItemIndex = index(pTC->row(), 2, sParentIndex);
              addEntry(sCItemIndex, id, pTC);
              break;
           }

           case cAbstractTreeItem::TC:
           {
              const tCanGUIData* pData = m_pDataHandler->getEntryByID(id);

              if(nullptr == pData)
              {
                 return;
              }

              break;
           }

           default:
              break;
           }
        }

这个函数是这样调用的:

  addEntry(QModelIndex(), DataId, getRootItem());

数据结构如下:

        TA
        |
        | -- TB
        | | | |
        | | | | -- TC
        | | | | -- TC

addentry 函数正确添加条目并发出 datachanged 信号,但树视图未更新。

但如果我发出 layoutChanged 信号,treeview 会显示正确的数据。如果我在调用 addEntry 之前和之后调用 beginResetModel 和 EndResetModel,就会发生类似的情况。但在这种情况下,另一个错误发生,即当调用 addEntry 的速率太大时,如果我使用箭头键更改选择,它会在 mapToSource 中崩溃(可能它在重置操作的中间并且模型索引在代理过滤器中变得无效)

对此有何建议?

标签: c++qtqtreeview

解决方案


您是否在插入新项目之前调用 beginInsertRows(...) 并在之后调用 endInsertRows() ?

https://doc.qt.io/qt-5/qabstractitemmodel.html#beginInsertRows


推荐阅读