Ich habe mir mein eigenes Model geschrieben (abgeleitet von QAbstractItemModel), welches mit einem TreeView verwendet wird.
Die Datenhaltung erreiche ich durch eine eigene Item-Klasse ( wie es das "Simple DOM Model" Qt Example auch macht ). Also bei einem "createIndex" wird als void* ein Item übergeben, sowie bspw. beim data() / setData() Aufruf der internalPointer des QModelIndex abgerufen und über das zugehörige Item Daten abgefragt / editiert.
Das Anzeigen der "Item"-Daten im View, sowie das Editieren von Daten funktioniert soweit problemlos. Auch das Einfügen von weiteren Zeilen klappt wunderbar, indem bei meiner implementierten insertRows Funktion:
1. beginInsertRows mit Angabe des Parents und der Angabe, an welcher Position wie viele Zeilen hinzugefügt werden sollen.
2. Die neuen Item Objekte passend der Vater/Kind Beziehung erzeugt und eingefügt werden.
3. mit endInsertRows die Behandlung abgeschlossen wird.
>> Ich hab das dann so verstanden, dass durch die Funktionen begin/endInsertRows dem Model bzw. dem View mitgeteilt wird, dass es dort neue Zeilen gibt und dann der View das Model anhand der vorhandenen Funktionen wie index() sich das zugehörige QModelIndex zu dem neuen Item verschafft und mittels data() dann die Daten des Items abfragt.
Die Probleme entstehen nun beim Entfernen von Zeilen:
Also ich habe in meiner Model-Klasse die removeRows() implementiert. Auch hier wird erst ein beginRemoveRows(..) durchgeführt, dann die zugehörigen Items der betroffenen Zeilen gelöscht und abschließend ein endRemoveRows aufgerufen.
Ein Beispiel (im Anhang ein Screenshot):
Es gibt 3 Zeilen mit je 3 Spalten. Alle 3 QModelIndex einer Zeile zeigen mit ihrem internalPointer auf das gleiche Item. Also für jede Zeile existiert ein zugehöriges Item.
In diesem Bsp sind Zeile 2 und 3 "Kinder" von Zeile 1 (siehe Screenshot).
Ich möchte nun Zeile 3 löschen, so rufe ich meine FUnktion removeRows auf und übergebe den Parent-QModelIndex (erhalte ich durch den View => currentIndex() (Zeile 3) Aufruf und davon frage ich das parent() an) und übergebe "1" für param "row" (Zeile 2 ist "0" und Zeile 3 ist "1" vom Parent aus gezählt) und "1" für param "count". Innerhalb wird dann die beginRemoveRows aufgerufen und Folgendes übergeben: der Parent-QModelIndex , der param "row" für "first" und "row+count-1" für "last".
Anschließend wird das zugehörige Item gelöscht und endRemoveRows aufgerufen.
Damit ist die Behandlung abgeschlossen, aber sporadisch kommt es zur Access-Violation, weil beispielsweise vom Model die Funktion parent aufgerufen wird und ein QModelIndex übergeben wird, der auf das gelöschte Item zeigt???!! In den wenigsten Fällen funktioniert es und die Zeile ist weg.
Ich hätte damit gerechnet, so wie bei BeginInsertRows(), dass mit BeginRemoveRows dem Model / View mitgeteilt wird, dass die Zeile 3 nicht mehr existiert und darauf keine Abfragen mehr gemacht werden (also das ein QModelIndex auf die Zeile3 mit Spaltenangabe verweist).
Leider kann ich meinen Code gerad nicht hier anzeigen, da ich momentan nicht an dem Rechner sitze, wo ich entwickle (könnt ich noch nachholen, falls erwünscht).
Kann nur nochmal sagen, dass mein Model/Item dem Qt-Example sehr nahe kommt.
Von daher gibt es bestimmt jemanden, der dies auch gemacht hat und eventuell auf ähnliche Probleme gestoßen ist und einen
Danke + gute Nacht
PS: Sorry für den etwas zu lang geratenen Text.