I\'m writing a Twitter client. I implemented TweetItem
and TweetModel
. The issue is that there is a role in TweetItem
called ori
My guess is that you got undefined not on accessing your TweetItem object, but on trying to get id out of it.
As it looks, your implementation of QAbstractItemModel in TweetItem is simply incorrect. Not does it's data method accepts any index, nor it implements rowCount. Consult Qt documentation on how to implement QAbstractItemModel interface correctly if you still wan't to use it.
My advice, to achieve what you want, is to subclass QObject instead and provide your additional data as it's named properties to use them in QML. See this page of Qt guidelines on how to bind your QObject with QML.
undefined
because, because your TweetItem.original
is in fact None
.I'm not sure what you are trying to accomplish, but I want to clear some possible misunderstandings. QAbstractItemModel
is a model class too, it's somewhat strange to see
def data(self, index, role):
return self.tweets[index.row()].data(role)
there.
As was suggested by dant3 use QObject with properties.
Here is an example how to do it:
import sys
from PyQt4 import QtCore, QtGui, QtDeclarative
from PyQt4.QtCore import pyqtProperty, pyqtSignal, QObject
class TweetModel(QtCore.QAbstractListModel):
def __init__(self, prototype, parent=None):
QtCore.QAbstractListModel.__init__(self, parent)
self.setRoleNames(prototype.roles)
self.tweets = []
def appendRow(self, item):
self.tweets.append(item)
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.tweets)
def data(self, index, role):
return self.tweets[index.row()].data(role)
class TweetItem(QObject):
roles = {
QtCore.Qt.UserRole + 1: 'id',
QtCore.Qt.UserRole + 6: 'original',
}
id_changed = pyqtSignal()
def __init__(self, id=None, original=None, parent=None):
QObject.__init__(self, parent=parent)
self._data = {'original': original}
self.id = id
def data(self, key):
return self._data[self.roles[key]]
@pyqtProperty(str, notify=id_changed)
def id(self):
return self._data['id']
@id.setter
def id(self, value):
if self._data.get('id') != value:
self._data['id'] = value
self.id_changed.emit()
if __name__ == "__main__":
model = TweetModel(TweetItem)
item = TweetItem("0001", None, model)
model.appendRow(TweetItem("0002", item, model))
App = QtGui.QApplication(sys.argv)
view = QtDeclarative.QDeclarativeView()
view.rootContext().setContextProperty("mymodel", model)
view.setSource(QtCore.QUrl.fromLocalFile("main.qml"))
view.show()
App.exec_()
The QML file remains the same.
I didn't make original
a property, since you get it as model data, but you can make it in the same fashion as id
.