如果没有layoutChanged

时间:2018-09-18 14:06:34

标签: c++ qt 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函数可正确添加条目并发送数据已更改的信号,但树视图不会更新。

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

对此有何建议?

1 个答案:

答案 0 :(得分:0)

在插入新项之前调用beginInsertRows(...),在插入新项之后调用endInsertRows(...)吗?

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