2016-10-11 28 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); 
} 

我々はマイナーなメモリリークを気にしない場合は今、これはうまく動作します。 ^^

しかし、私は最初に/選択された行オブジェクトでdeleteコマンドを実行しようとした場合 - その後、2つの例外のいずれかが発生:

  1. を行が子を持つ: 例外がスローさ:は、アクセス違反をお読みください。これは0xDDDDDDDDでした。
  2. 行に子がありません。 例外がスローされました:書き込みアクセス違反。 _Parent_proxyは0x64F30630でした。

私はコードを短くしましたが、うまくいけば私のエラーが含まれています。または、誰かがアイテムを追加/削除する方法を示す良いQTreeView/QAbstractItemModelの例を知っていますか?

種類が ソラ

+1

まず:Yuoは、この行を交換する必要が)) – Fabio

+0

ありがとう! :)これは例外の原因であり、現在は機能しています。回答を再投稿すると解決済みとマークします。 – Sora

答えて

0

に関しては、私はMyModel::remove方法に誤りがあると思います。 beginRemoveRowsは、インデックス自体ではなく、親インデックスを最初のパラメータとしてとります。 beginRemoveRows(index.parent()、index.row()、index.row(:私はあなたが呼び出すbeginRemoveRowsで親インデックスを使用するために持っていると思うすべての

beginRemoveRows(index.parent(), index.row(), index.row()); 
関連する問題