Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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?


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    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


  • Lifetime Qt Champion

    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 roles

    P.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;
    }
    
    

  • Lifetime Qt Champion

    @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_OBJECT

    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)
    {
    }
    

    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;
    }

Log in to reply