take a bit more care when deleting graphicsitems from the scene

This ensures that
a) underlying C++ objects are not deleted when another python reference
graphicsitems still exists
b) children object are not tried to be deleted twice
This commit is contained in:
Martin Baeuml
2011-09-14 15:39:53 +02:00
parent 7e00a1a058
commit 54556bc715
2 changed files with 32 additions and 7 deletions
+1 -2
View File
@@ -394,8 +394,7 @@ class LabelTool(QObject):
def deleteSelectedAnnotations(self):
if self._mainwindow is not None:
for item in self._mainwindow.scene.selectedItems():
item.modelItem().delete()
self._mainwindow.scene.deleteSelectedItems()
def exitInsertMode(self):
if self._mainwindow is not None:
+31 -5
View File
@@ -105,6 +105,14 @@ class AnnotationScene(QGraphicsScene):
else:
LOG.warn("Could not find item for annotation with class '%s'" % label_class)
def deleteSelectedItems(self):
# some (graphics) items may share the same model item
# therefore we need to determine the unique set of model items first
# must use a dict for hashing instead of a set, because objects are not hashable
modelitems_to_delete = dict((id(item.modelItem()), item.modelItem()) for item in self.selectedItems())
for item in modelitems_to_delete.values():
item.delete()
def onInserterFinished(self):
self.sender().inserterFinished.disconnect(self.onInserterFinished)
self._labeltool.exitInsertMode()
@@ -139,7 +147,12 @@ class AnnotationScene(QGraphicsScene):
self.clearMessage()
def clear(self):
QGraphicsScene.clear(self)
# do not use QGraphicsScene.clear(self) so that the underlying
# C++ objects are not deleted if there is still another python
# reference to the item somewhere else (e.g. in an inserter)
for item in self.items():
if item.parentItem() is None:
self.removeItem(item)
self._scene_item = None
def addItem(self, item):
@@ -255,8 +268,7 @@ class AnnotationScene(QGraphicsScene):
else:
# selection mode
if event.key() == Qt.Key_Delete:
for item in self.selectedItems():
item.modelItem().delete()
self.deleteSelectedItems()
event.accept()
elif event.key() == Qt.Key_Escape:
@@ -294,8 +306,13 @@ class AnnotationScene(QGraphicsScene):
return
for row in range(first, last+1):
item = self.itemFromIndex(index.child(row, 0))
if item is not None:
items = self.itemsFromIndex(index.child(row, 0))
for item in items:
# if the item has a parent item, do not delete it
# we assume, that the parent shares the same model index
# and thus removing the parent will also remove the child
if item.parentItem() is not None:
continue
self.removeItem(item)
def rowsRemoved(self, index, first, last):
@@ -309,6 +326,15 @@ class AnnotationScene(QGraphicsScene):
return item
return None
def itemsFromIndex(self, index):
items = []
for item in self.items():
# some graphics items will not have an index method,
# we just skip these
if hasattr(item, 'index') and item.index() == index:
items.append(item)
return items
#
# message handling and displaying
#______________________________________________________________________________________________________