Я подклассифицирую QAbstractItemModel
для отображения элементов в QTreeView
, и в этом подклассе (projectModel
) у меня есть функция для удаления выбранного в данный момент индекса в древовидном представлении. Component
класс используется для представления всех членов модели:QModelIndex становится недопустимым при удалении строк
void
projectModel::deleteComponent()
{
QModelIndex child_index = _treeview->selectionModel()->currentIndex();
Component* child = static_cast<Component*>(child_index.internalPointer());
Component* parent = child->Parent();
QModelIndex parent_index = createIndex(parent->row(), 0, parent);
int row = child->row();
beginRemoveRows(parent_index, row, row);
parent->delete_child(child);
endRemoveRows();
}
Родительские и дочерние indicies и сырые указатели хороши только перед вызовом beginRemoveRows
; Отладчик показывает, что они указывают на правильный элемент и его родительский элемент. Однако программа вылетает после вызова beginRemoveRows
. В частности, он выходит из строя в projectModel::parent()
:
QModelIndex
projectModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
Component* item = getItem(index); //Fails to cast index internal pointer to a valid Component*
Component* parentItem = item->Parent();
if (parentItem == _rootnode)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
Когда я нарушу на аварии и изучить вывод отладчика, это показывает, что в функции parent()
переменная item
мусор. Как-то похоже, что мой QModelIndex
поврежден между вызовом deleteComponent
и вызовом parent
. Есть ли что-то явно неправомерное в том, что я делаю, или проблема, возможно, более тонкая?
Сторона примечания: модель никогда не должна содержать ссылок на представление, так как она вполне применима для использования модели с нулевыми представлениями, а также с «представлениями», которые не подкласса «QAbstractItemView». Метод 'deleteComponent' принадлежит где-то за пределами класса модели. Скорее всего, вы должны подклассифицировать 'QTreeView'. –
Я также 'Q_ASSERT (child_index.isValid())', так как он не должен быть действительным. –
Что такое стек вызовов при сбое? Вероятно, вы не должны называть 'deleteComponent', в то время как любой код представления, который у вас отсутствует, находится в стеке вызовов. –