Hi list, I read the very good example in the wiki (http://developer.qt.nokia.com/wiki/Selectable_list_of_Python_objects_in_QML) and the thread "Updating QML ListView content from PySide". It helped me a lot, but I still have a question.
In these examples, the list of wrappers is generated once for all (things =
[ThingWrapper(thing) forthing in people]). But in reality, I don't want to do
that, because I have a large number of items which come from a database.
So I tried to modify the example in order to call the wrapper only when the
model returns data. But in my first tries, it didn't work, I think because the
reference to the object was lost.
My first bad idea was to keep reference with something like this (but it keeps
all items in memory, which is what I want to avoid).
# in realty, things won't be a list of items (because in this case, keeping a
list of wrappers wouldn't cost too much) but an iterator for example
#things = [ThingWrapper(thing) forthing in people] becomes
things = people
# in ThingListModel.__init__
self._remember_me_list = []
# in ThingListModel.data
remember_me = ThingWrapper(self._things[index.row()])
self._remember_me_list.append(remember_me)
return remember me
My second idea was to use a global variable to keep reference in the python
world to the object (I read this trick in the "Updating QML ListView content
from PySide" thread but to solve another problem) :
# in ThingListModel.data
global remember_me
remember_me = ThingWrapper(self._things[index.row()])
return remember_me
I attached the example from the wiki with my modifications. Is it the good the
approach, or do I miss something ?
Thanks for the help,
Jean-Baptiste Rudant
import sys
from PySide import QtCore
from PySide import QtGui
from PySide import QtDeclarative
from PySide import QtOpenGL
class ThingWrapper(QtCore.QObject):
def __init__(self, thing):
QtCore.QObject.__init__(self)
self._thing = thing
def _name(self):
return str(self._thing)
changed = QtCore.Signal()
name = QtCore.Property(unicode, _name, notify=changed)
class ThingListModel(QtCore.QAbstractListModel):
COLUMNS = ('thing',)
def __init__(self, things):
QtCore.QAbstractListModel.__init__(self)
self._things = things
self.setRoleNames(dict(enumerate(ThingListModel.COLUMNS)))
#alternative :
#self._remember_me_list = []
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self._things)
def data(self, index, role):
if index.isValid() and role == ThingListModel.COLUMNS.index('thing'):
#return self._things[index.row()]
global remember_me
remember_me = ThingWrapper(self._things[index.row()])
#alternative :
#self._remember_me_list.append(remember_me)
return remember_me
return None
class Controller(QtCore.QObject):
@QtCore.Slot(QtCore.QObject)
def thingSelected(self, wrapper):
print 'User clicked on:', wrapper._thing.name
if wrapper._thing.number > 10:
print 'The number is greater than ten!'
app = QtGui.QApplication(sys.argv)
m = QtGui.QMainWindow()
view = QtDeclarative.QDeclarativeView()
glw = QtOpenGL.QGLWidget()
view.setViewport(glw)
view.setResizeMode(QtDeclarative.QDeclarativeView.SizeRootObjectToView)
class Person(object):
def __init__(self, name, number):
self.name = name
self.number = number
def __str__(self):
return 'Person "%s" (%d)' % (self.name, self.number)
people = [
Person('Locke', 4),
Person('Reyes', 8),
Person('Ford', 15),
Person('Jarrah', 16),
Person('Shephard', 23),
Person('Kwon', 42),
]
#things = [ThingWrapper(thing) for thing in people]
#in realty, things won't be a list of items (because in this case, keeping a
list of wrappers wouldn't cost too much) but an iterator for example
things = people
controller = Controller()
thingList = ThingListModel(things)
rc = view.rootContext()
rc.setContextProperty('controller', controller)
rc.setContextProperty('pythonListModel', thingList)
view.setSource('PythonList.qml')
m.setCentralWidget(view)
m.show()
app.exec_()
PythonList.qml
Description: Binary data
_______________________________________________ PySide mailing list [email protected] http://lists.openbossa.org/listinfo/pyside
