Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Defining roles in QAbstractItemModel
Forum Updated to NodeBB v4.3 + New Features

Defining roles in QAbstractItemModel

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 2 Posters 4.3k 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.
  • C Offline
    C Offline
    clarity
    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
    • jpnurmiJ Offline
      jpnurmiJ Offline
      jpnurmi
      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.

      C 1 Reply Last reply
      0
      • jpnurmiJ jpnurmi

        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.

        C Offline
        C Offline
        clarity
        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

        jpnurmiJ 1 Reply Last reply
        0
        • C clarity

          @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

          jpnurmiJ Offline
          jpnurmiJ Offline
          jpnurmi
          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());
          }
          
          C 1 Reply Last reply
          0
          • jpnurmiJ jpnurmi

            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());
            }
            
            C Offline
            C Offline
            clarity
            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);
                            }
                        }
                    }
            
            jpnurmiJ 1 Reply Last reply
            0
            • C clarity

              @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);
                              }
                          }
                      }
              
              jpnurmiJ Offline
              jpnurmiJ Offline
              jpnurmi
              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.

              C 1 Reply Last reply
              0
              • jpnurmiJ jpnurmi

                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.

                C Offline
                C Offline
                clarity
                wrote on last edited by clarity
                #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;
                }

                jpnurmiJ 1 Reply Last reply
                0
                • C clarity

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

                  jpnurmiJ Offline
                  jpnurmiJ Offline
                  jpnurmi
                  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().

                  C 1 Reply Last reply
                  0
                  • jpnurmiJ jpnurmi

                    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().

                    C Offline
                    C Offline
                    clarity
                    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 Extensions
                    • Unsolved