Я реализовал иерархический 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, древовидная структура отобразит правильные данные. Аналогичный случай происходит, если я вызываю beginResetModel и EndResetModel до и после вызова addEntry. Но в этом случае возникает другая ошибка: когда скорость вызова addEntry слишком велика, если я изменяю выбор с помощью клавиш со стрелками, происходит сбой в mapToSource (вероятно, в середине операции сброса, и индексы модели становятся недействительными в прокси-фильтре)
Любое предложение по этому поводу?