2016-10-11 4 views
0

Я написал класс, полученный из QAbstractModelItem. Он используется в QTreeView. К сожалению, в официальном примере документации не показано, как добавлять или удалять элементы модели. Я думал, что это будет легко сделать, поэтому я взломал свой путь. Проблема в том, что удаление выделенного объекта вызывает исключение. Пример:QTreeView/QAbstractItemModel - исключение вызывает причины

Пользователь нажимает на строку в QTreeView и хочет удалить ее со всеми ее дочерними элементами (если есть). Это код, который выполняется:

MyModel.cpp: 

// This gets called with the QModelIndex of the currently selected row. 
void MyModel::remove(const QModelIndex &index) { 
    if (!index.isValid()) 
     return; 
    MyItem * selectedItem = static_cast<MyItem*>(index.internalPointer()); 
    beginRemoveRows(index, index.row(), index.row()); 
    // Call the method on the selected row object that will delete itself and all its children: 
    selectedItem->destroy(); 
    endRemoveRows(); 
} 

MyItem.h: 

// A pointer list with child items. 
std::vector<MyItem*> children; 

MyItem.cpp: 

// Deletes all children of this object and itself. 
void MyItem::destroy(bool isFirst) { 
    if (children.size() > 0) { 
     // Each child needs to run this function, to ensure that all nested objects are properly deleted: 
     for each (auto child in children) 
      child->destroy(false); 
     // Now that the children have been deleted from heap memory clear the child pointer list: 
     children.clear(); 
    } 
    // This boolean determines wether this object is the selected row/highest object in the row hierachy. Remove this object from the parent's pointer list: 
    if(isFirst) 
     parent->removeChild(this); 
    // And lastly delete this instance: 
    if(!isFirst) // This will cause a memory leak, but it is necessary 
     delete this; // <- because this throws an exception if I run this on the first object. 
} 

// Removes a single child reference from this instance's pointer list. 
void MyItem::removeChild(MyItem * child) 
{ 
    auto it = std::find(children.begin(), children.end(), child); 
    children.erase(it); 
} 

Теперь это работает отлично, если мы не против небольшой утечки памяти. ^^

Но если я пытаюсь запустить команду удаления на первый/выбранный объекте строки - то один из двух исключений встречается:

  1. Строка имеет ребенок: Exception брошенное: чтение нарушения доступа. это было 0xDDDDDDDD.
  2. В строке нет детей: Исключение бросили: Нарушение права на запись. _Parent_proxy был 0x64F30630.

Я сохранил код коротким, но, надеюсь, он содержит мою ошибку. Или кто-нибудь знает хороший пример QTreeView/QAbstractItemModel, который показывает, как добавлять/удалять элементы?

Сердечные приветы Сора

+1

Прежде всего, я думаю, вы должны использовать родительский индекс в beginRemoveRows называют: beginRemoveRows (index.parent(), index.row(), index.row ()) – Fabio

+0

Большое вам спасибо! :) Это было причиной исключений, и теперь это работает. Если вы ответите на свой ответ, я помечаю его как решенный. – Sora

ответ

0

Я думаю, что есть ошибка в методе MyModel::remove. beginRemoveRows принимает в качестве первого параметра родительский индекс, а не сам индекс. ЮО должны заменить строку с этим:

beginRemoveRows(index.parent(), index.row(), index.row()); 
Смежные вопросы