I'm new with Qt , so please bear with me .
I've successfully managed to populate a ListView from a StringList and a QList of Object*
What I'm struggling now with is to populate a ListView in QML using a class defined in C++ that derives QAbstractListModel.
Here's the prototype of my CPP class :
class MessageListEntryModel : public QAbstractListModel
{
Q_OBJECT
public:
enum eMLERoleTypes
{
MLERT_MSG = Qt::UserRole+1,
MLERT_COLOR
};
MessageListEntryModel(QObject* parent=0);
virtual ~MessageListEntryModel();
void AddEntry(QString aMessage, QColor aColor);
// pure virtuals implementations
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const ;
int columnCount(const QModelIndex &parent = QModelIndex()) const ;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const ;
QHash<int,QByteArray> roleNames();
private:
QList<MessageEntry*> m_vpMessages;
MessageEntry is a simple class that contains 2 memebers , a QColor and a QString (the class doesn't extend QObject).
I had to implement all the above functions since they're pure virtual in an underlying class (is this normal? so far in tutorials/samples people mentioned only about roleNames and data).
The implementation of roleNames and data are as following :
QHash<int,QByteArray> MessageListEntryModel::roleNames()
{
QHash<int,QByteArray> rez;
rez[MLERT_MSG]="message";
rez[MLERT_COLOR]="messagecolor";
return rez;
}
QVariant MessageListEntryModel::data(const QModelIndex &index, int role) const
{
qDebug()<<" Data asked for "<<index.row()<<" and role "<<role;
if (index.row()<0 || index.row()>=m_vpMessages.size())
{
return QVariant();
}
MessageEntry* entry = m_vpMessages[index.row()];
if (role == MLERT_MSG)
{
return QVariant::fromValue(entry->message);
} else if (role == MLERT_COLOR)
{
return QVariant::fromValue(entry->messageColor);
}
// should be unreachable code
return QVariant();
}
The QML portion of the List View is something like this :
ListView {
id: quickMessageListdata
model: quickListModel
delegate: Rectangle {
width: 400
height: 25
color:"#000000"
Text{
text: model.message
color: model.messagecolor
}
}
So far this is my understanding on how to implement things in CPP and QML. For linking these two, I use the following code :
MessageListEntryModel* model =new MessageListEntryModel();
// Add various entries
...
// assign model in QML
m_pViewRef->rootContext()->setContextProperty("quickListModel",model);
With the code above, when running nothing is displayed in the ListView and I'm getting the following errors :
Unable to assign [undefined] to QString
Unable to assign [undefined] to QColor
I'm also registering the model class to be exported to QML (don't know if this is necessary) :
qmlRegisterType<MessageListEntryModel> ("dlti.exported",1,0,"MessageListEntryModel");
So it's quite obvious that either I missuderstood the proper use of a QAbstractListItem derived class OR I miss a simple vital key information.
I would appreciate some pointers to some relevant samples / tutorials (one that also shows you how to properly access data from the model in QML, since I've noticed that in CPP it never passes through the data function).
Also please notice that I'm using qt5 , so qt4.8 samples won't do the trick.
EDIT
After long hours of frustrations, I finally managed what was wrong with the damn thing :
My roleNames function signature was wrong ! The correct signature for overload is :
protected :
QHash<int,QByteArray> roleNames() const;
Please notice the protected and the const modifiers.
After declaring the function the correct way , it all worked fine.
For further notice, implementing data and rowCount was sufficient :).
Thanks for the help. I will accept BaCaRoZzo's answer since I only manged to figure this out after looking over the code from the example.
As a side note, it works well with both message and model.message.