Fix garbage collection of ListModelMap items
Prevent ListModel items from being deleted on the C++ side (specially when using .get() from QML and a new ListModel is created) by setting their parent to the ListModelMap.
This commit is contained in:
		@@ -5,15 +5,17 @@ from typing import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from namedlist import namedlist
 | 
					from namedlist import namedlist
 | 
				
			||||||
from PyQt5.QtCore import (
 | 
					from PyQt5.QtCore import (
 | 
				
			||||||
    QAbstractListModel, QModelIndex, Qt, pyqtProperty, pyqtSlot
 | 
					    QAbstractListModel, QModelIndex, QObject, Qt, pyqtProperty, pyqtSlot
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NewValue = Union[Mapping[str, Any], Sequence]
 | 
					NewValue = Union[Mapping[str, Any], Sequence]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ListModel(QAbstractListModel):
 | 
					class ListModel(QAbstractListModel):
 | 
				
			||||||
    def __init__(self, initial_data: Optional[List[NewValue]] = None) -> None:
 | 
					    def __init__(self,
 | 
				
			||||||
        super().__init__()
 | 
					                 initial_data: Optional[List[NewValue]] = None,
 | 
				
			||||||
 | 
					                 parent:       Optional[QObject]        = None) -> None:
 | 
				
			||||||
 | 
					        super().__init__(parent)
 | 
				
			||||||
        self._ref_namedlist          = None
 | 
					        self._ref_namedlist          = None
 | 
				
			||||||
        self._roles: Tuple[str, ...] = ()
 | 
					        self._roles: Tuple[str, ...] = ()
 | 
				
			||||||
        self._list:  list            = []
 | 
					        self._list:  list            = []
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,10 @@ from .list_model import ListModel
 | 
				
			|||||||
class ListModelMap(QObject):
 | 
					class ListModelMap(QObject):
 | 
				
			||||||
    def __init__(self) -> None:
 | 
					    def __init__(self) -> None:
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.dict: DefaultDict[Any, ListModel] = DefaultDict(ListModel)
 | 
					
 | 
				
			||||||
 | 
					        # Set the parent to prevent item garbage-collection on the C++ side
 | 
				
			||||||
 | 
					        self.dict: DefaultDict[Any, ListModel] = \
 | 
				
			||||||
 | 
					            DefaultDict(lambda: ListModel(parent=self))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pyqtSlot(str, result="QVariant")
 | 
					    @pyqtSlot(str, result="QVariant")
 | 
				
			||||||
@@ -21,6 +24,7 @@ class ListModelMap(QObject):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __setitem__(self, key, value: ListModel) -> None:
 | 
					    def __setitem__(self, key, value: ListModel) -> None:
 | 
				
			||||||
 | 
					        value.setParent(self)
 | 
				
			||||||
        self.dict[key] = value
 | 
					        self.dict[key] = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user