Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Defining roles in QAbstractItemModel
Qt 6.12 LTS is out! See what's new in the release blog

Defining roles in QAbstractItemModel

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 2 Posters 7.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #1

    I'm having issues with QAbstractItemModel roles. I have test code, but I can't seem to figure out how to display data using the roles.

    Here's the code.

    main.cpp:
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>

    #include <QtQml>

    #include <display.h>
    #include <modelclass.h>

    #include <string>
    using namespace std;

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    
    ModelClass mc;
    
    for (int i = 0; i < 10; ++i) {
        QString s {"index"};
        QModelIndex mi {};
        QVariant v {s};
        mc.setData(mi.child(i, 1), v, mc.BlockNum);
    }
    
    engine.rootContext()->setContextProperty("mc", &mc);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
    return app.exec();
    

    }

    modelclass.h:
    #ifndef MODELCLASS_H
    #define MODELCLASS_H

    #include <QObject>
    #include <QAbstractListModel>
    #include <QStringListModel>

    class ModelClass : public QAbstractItemModel
    {
    Q_OBJECT
    public:
    ModelClass();

    enum ModelRoles {
        BlockNum = Qt::UserRole + 1
    };
    
    
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    
    QModelIndex parent(const QModelIndex & index = QModelIndex()) const;
    QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
    
    QHash<int, QByteArray> roleNames() const;
    

    };

    #endif // MODELCLASS_H

    modelclass.cpp:
    #include "modelclass.h"

    ModelClass::ModelClass()
    {

    }

    int ModelClass::rowCount(const QModelIndex &parent) const {
    return 10;
    }

    int ModelClass::columnCount(const QModelIndex &parent) const
    {
    return 1;
    }

    QVariant ModelClass::data(const QModelIndex & index, int role) const {
    return QVariant();
    }

    QModelIndex ModelClass::parent(const QModelIndex & index) const {
    return index;
    }

    QModelIndex ModelClass::index(int row, int column, const QModelIndex & parent) const {
    return parent;
    }

    QHash<int, QByteArray> ModelClass::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[BlockNum] = "blocknum";
    return roles;
    }

    main.qml:
    import QtQuick 2.5
    import QtQuick.Controls 1.4
    import QtQuick.Layouts 1.2
    import QtQuick.Dialogs 1.2

    ApplicationWindow {
    id: mainWindow
    visible: true
    width: 640
    height: 480
    title: qsTr("Block Explorer")

        GridView {
            id: list
            model: mc
            anchors.fill: parent
            delegate: Text {
                text: blocknum
    
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        list.currentIndex = index;
                        messageDialog.show(display);
                    }
                }
            }
    
            highlight: Rectangle {
                 color: 'grey'
            }
    
            focus: true
    
            keyNavigationWraps: true
    
            Keys.onPressed: {
                var pageDown = currentIndex+10;
                var pageUp = currentIndex-10;
                if (event.key === Qt.Key_PageDown && event.modifiers === Qt.NoModifier) {
                    currentIndex = pageDown >= count ? count-1 : pageDown;
                    event.accepted = true;
                }
                if (event.key === Qt.Key_PageUp && event.modifiers === Qt.NoModifier) {
                    currentIndex = pageUp < 0 ? 0 : pageUp;
                    event.accepted = true;
                }
            }
    
        }
    
    MessageDialog {
        id: messageDialog
        title: qsTr("May I have your attention, please?")
    
        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }
    

    }

    Thanks!
    Ryan

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      QAbstractItemModel is a model interface. It doesn't store any data. When you implement the interface, it's up to you to decide how the data is stored. For a read-only model, you would implement data() so that it reurns values from an internal data structure, which could be a QList or QVector, for instance. If you want to make the model read-write, you need to implement setData() to store the values into the internal data structure of your choice.

      PS. For a simple list model, QAbstractListModel offers a little extra convenience. It implements columnCount() and index() for you, so you don't need to bother with them.

      ? 1 Reply Last reply
      0
      • ? A Former User

        QAbstractItemModel is a model interface. It doesn't store any data. When you implement the interface, it's up to you to decide how the data is stored. For a read-only model, you would implement data() so that it reurns values from an internal data structure, which could be a QList or QVector, for instance. If you want to make the model read-write, you need to implement setData() to store the values into the internal data structure of your choice.

        PS. For a simple list model, QAbstractListModel offers a little extra convenience. It implements columnCount() and index() for you, so you don't need to bother with them.

        ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        @jpnurmi How do roles factor in? Would data() return the QVector of the rows, and the roleNames return what position in the vector the columns are? For instance 0 = blocknum

        ? 1 Reply Last reply
        0
        • ? A Former User

          @jpnurmi How do roles factor in? Would data() return the QVector of the rows, and the roleNames return what position in the vector the columns are? For instance 0 = blocknum

          ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          data() returns data for the given index and role. For example

          QVariant ModelClass::data(const QModelIndex & index, int role) const {
              if (!index.isValid() && role != BlockNum)
                  return QVariant();
              return m_blockNums.at(index.row());
          }
          
          ? 1 Reply Last reply
          0
          • ? A Former User

            data() returns data for the given index and role. For example

            QVariant ModelClass::data(const QModelIndex & index, int role) const {
                if (!index.isValid() && role != BlockNum)
                    return QVariant();
                return m_blockNums.at(index.row());
            }
            
            ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #5

            @jpnurmi how do you register the roles?

            I want to do something like this:
            GridView {
            id: list
            model: mc
            anchors.fill: parent
            delegate: Text {
            text: blocknum

                        MouseArea {
                            anchors.fill: parent
                            onClicked: {
                                list.currentIndex = index;
                                messageDialog.show(display);
                            }
                        }
                    }
            
            ? 1 Reply Last reply
            0
            • ? A Former User

              @jpnurmi how do you register the roles?

              I want to do something like this:
              GridView {
              id: list
              model: mc
              anchors.fill: parent
              delegate: Text {
              text: blocknum

                          MouseArea {
                              anchors.fill: parent
                              onClicked: {
                                  list.currentIndex = index;
                                  messageDialog.show(display);
                              }
                          }
                      }
              
              ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              It looks like you have already roleNames() implemented. That's enough to make the role visible to QML. The framework will call data() with the appropriate index and role.

              ? 1 Reply Last reply
              0
              • ? A Former User

                It looks like you have already roleNames() implemented. That's enough to make the role visible to QML. The framework will call data() with the appropriate index and role.

                ? Offline
                ? Offline
                A Former User
                wrote on last edited by A Former User
                #7

                @jpnurmi I keep getting the following error:
                qrc:/main.qml:44: ReferenceError: blocknum is not defined

                Here is my code for roleNames():

                QHash<int, QByteArray> ModelClass::roleNames() const {
                QHash<int, QByteArray> roles;
                roles[BlockNum] = "blocknum";
                return roles;
                }

                ? 1 Reply Last reply
                0
                • ? A Former User

                  @jpnurmi I keep getting the following error:
                  qrc:/main.qml:44: ReferenceError: blocknum is not defined

                  Here is my code for roleNames():

                  QHash<int, QByteArray> ModelClass::roleNames() const {
                  QHash<int, QByteArray> roles;
                  roles[BlockNum] = "blocknum";
                  return roles;
                  }

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #8

                  I can't spot any mistake in roleNames(), but how does the rest of the code look like now? In the first snippet, index() and parent() seemed wrong. Have you switched to QAbstractListModel? Then you can simply remove your reimplementations of index(), parent() and columnCount().

                  ? 1 Reply Last reply
                  0
                  • ? A Former User

                    I can't spot any mistake in roleNames(), but how does the rest of the code look like now? In the first snippet, index() and parent() seemed wrong. Have you switched to QAbstractListModel? Then you can simply remove your reimplementations of index(), parent() and columnCount().

                    ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #9

                    @jpnurmi said:

                    QAbstractListModel

                    That fixed it! Thank you so much!

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt
                    • Unsolved