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_()

Attachment: PythonList.qml
Description: Binary data

_______________________________________________
PySide mailing list
[email protected]
http://lists.openbossa.org/listinfo/pyside

Reply via email to