Solved QStandardItemModel & Inheritance
-
Hi, I subclassed QStandardItemModel to be able to use it in Qml (by changing the roles):
#ifndef ALBUMMODEL_H
#define ALBUMMODEL_H#include <QStandardItemModel>
class AlbumModel : public QStandardItemModel
{
Q_OBJECT
QHash<int, QByteArray> m_roles;public:
enum AlbumRoles {
// displayRole = Qt::DisplayRole,
// decorationRole = Qt::DecorationRole,
albumRole = Qt::UserRole + 1,
artistRole = Qt::UserRole + 2,
artworkRole = Qt::UserRole + 3,
genreRole = Qt::UserRole + 4,
yearRole = Qt::UserRole + 5
};AlbumModel(QObject *parent = 0) : QStandardItemModel(parent) {
// m_roles[displayRole] = "DisplayRole";
// m_roles[decorationRole] = "DecorationRole";
m_roles = QStandardItemModel::roleNames();
m_roles[albumRole] = "albumRole";
m_roles[artistRole] = "artistRole";
m_roles[artworkRole] = "artworkRole";
m_roles[genreRole] = "genreRole";
m_roles[yearRole] = "yearRole";
}protected:
QHash<int, QByteArray> roleNames() const
{
return m_roles;
}
};#endif //
this is the qml:
GridView{ id: grid model: AlbumModel cellWidth: 100 cellHeight: cellWidth delegate: Rectangle{ width: grid.cellWidth height: grid.cellWidth Image{ id: image anchors.fill: parent height: width source: "file://" + artworkRole } } }
but now I can't use the same model in c++and my QListView doesn't show DecorationRole and DisplayRole. I want to use the model in both C++ and Qml
how can I fix the problem?
-
Hi,
How did you implement the data method ? Are you returning the base class implementation for roles that are outside
m_roles
? -
Hi @SGaist
the code above is all I did and I don't know how to do that I thought this line would take care of that:m_roles = QStandardItemModel::roleNames();
but it does not. what should I do?
-
Giving role names is one thing, however the model can't possibly map them to the data you feed it with.
Take a look a the Using C++ Models with Qt Quick Views chapter of Qt's documentation and the matching example.
-
Well @SGaist
I have written this code based on the animal example of the page you posted and This code works perfectly in my Qml and I don't have a problem there and I can use all of the data but however I want to use the same model in C++ and a QListVew but the ListView doesn't show Decoration or Display role of the items and I don't know what to do -
I started implementing a proxy to convert columns to roles, it's available here: http://pastebin.com/70KjfZzm
Due to lack of time I did not test it so it might not work.
The idea is to set up the model the C++ way with columns then the proxy takes care of converting it to roles. The Qt::DisplayRole of each column will have the role name equal to what you set in the headerData for the column, the other roles will be named col#RoleName (e.g. col1toolTip)Please note that if you use this proxy you cannot use any role >=1024 so you will only have the range [Qt::UserRole;1023] to store your custom data
-
Hi @VRonin
I don't want my model to have more than one column and this complicates things my question is simpler than this answer -
The answer is simple: implement the roles you need in the data function.
The example only return values for the custom TypeRole and SizeRole roles. Since you want to use that model with a QListView, you have to return data for the roles you are interested in.
-
Then I fail to understand what the problem might be, changing the role names should have no impact on the C++ model. Could you try using just QStandardItemModel in C++ if it works?
Could you please show us the code of where this model gets used?@SGaist
He does not reimplement data() so the QStandardItemModel data() should work fine for all other rolesP.S.
this code:m_roles = QStandardItemModel::roleNames(); m_roles[albumRole] = "albumRole"; m_roles[artistRole] = "artistRole"; m_roles[artworkRole] = "artworkRole"; m_roles[genreRole] = "genreRole"; m_roles[yearRole] = "yearRole";
should not be in the constructor but in roleNames()
QHash<int, QByteArray> roleNames() const { QHash<int, QByteArray> result= QStandardItemModel::roleNames(); result[albumRole] = "albumRole"; result[artistRole] = "artistRole"; result[artworkRole] = "artworkRole"; result[genreRole] = "genreRole"; result[yearRole] = "yearRole"; return result; }
-
@VRonin Argle ! I've read QAbstractItemModel rather than Standard… Thanks for the pointer !
In that case, the items should contain something for the DisplayRole and DecorationRole roles. If the items only have data for the other roles then that's normal that the QListView doesn't show anything. Second possibility is to reimplement data to map the custom roles on DisplayRole and Decoration role.
-
Hi
Thank you for helping I needed this and I finally did it:class AlbumModel : public QStandardItemModel
{
Q_OBJECTpublic:
enum AlbumRoles {
DisplayRole = Qt::DisplayRole,
DecorationRole = Qt::DecorationRole,
albumRole = Qt::UserRole + 1,
artistRole = Qt::UserRole + 2,
artworkRole = Qt::UserRole + 3,
genreRole = Qt::UserRole + 4,
yearRole = Qt::UserRole + 5
};AlbumModel(QObject *parent = 0) : QStandardItemModel(parent) { }
protected:
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> m_roles;m_roles[DecorationRole] = "DecorationRole"; m_roles[DisplayRole] = "DisplayRole"; m_roles[yearRole] = "yearRole"; m_roles[albumRole] = "albumRole"; m_roles[genreRole] = "genreRole"; m_roles[artistRole] = "artistRole"; m_roles[artworkRole] = "artworkRole"; return m_roles; }