[PyQt] Problems with QQmlListProperty and Qml object ownership
Juan Pedro Bolívar Puente
raskolnikov at gnu.org
Tue Oct 29 00:22:35 GMT 2013
Hi!
I am using PyQt5 and while I love the approach I have found a couple of
serious issues, the latter one becoming a real showstopper. I have
tried both with Qt 5.1 and 5.2.
1. Objects are not kept alive by Qml, meaning the application soon
crashes if I do not keep the references alive. I am now keeping all my
objects alive, but sadly this means I have some memory leaks now. Is
there a way to fix it? I was considering moving parts of the
application to C++ in the future: can this problem be solved in C++ or
is it an inherent limitation of Qml memory model?
2. I am having very weird crashes with QQmlListProperty. First, my usage
of QQmlListProperty looks a bit like this (not exactly, but you get the
idea):
class ListHolder(QObject):
def __init__(self, wrapped_list):
super(ConstListWrapper, self).__init__()
self._wrapped_list = wrapped_list
def __len__(self):
return len(self._wrapped_list)
def __getitem__(self, param):
return self._wrapped_list[wrapped_list]
class SomeObjectWithAList(QObject):
myListChanged = pyQtSignal(QQmlListProperty)
@pyQtProperty(QQmlListWrapper)
def myList(self):
if self._list_holder is None:
self._list_holder = ListHolder(self._the_list)
if self._list_wrapper is None:
self._list_wrapper = QQmlListProperty(
ListHolder,
self._list_holder,
count = len,
at = operator.getitem,
clear = lambda *a: None,
append = lambda *a: None)
return self._list_wrapper
def somethingChangedInTheList(self):
self.myListChanged.emit(self.myList)
...
There are a couple of funny things in that code:
a) If I remove the clear and append operations, I get crashes more often.
b) In either case, when I bind the 'myList' property as model of
Repeater or ListView elements, only the two first elements of the list
are shown.
c) Most often when using the list in repeater or list views, the
application crashes at the end on the garbage collector, in some
Py_GetArgcArgv function called from PyDict_Contains called from
_Py_GcObject_Track or something like that.
I have tried many variations of these, some of which do not involve the
ListHolder object at all, but this is the "least crashing" variation I
have so far... Did I make a very stupid mistake? Google gives me very
few cases of people using QQMlListProperty from PyQt, giving me the
impression it might be a bit unsupported? Any clue?
Thanks a lot!
JP
More information about the PyQt
mailing list