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.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.
  • C Offline
    C Offline
    clarity
    wrote on 19 Feb 2016, 15:34 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
    • J Offline
      J Offline
      jpnurmi
      wrote on 19 Feb 2016, 16:42 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 19 Feb 2016, 17:24
      0
      • J jpnurmi
        19 Feb 2016, 16:42

        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 19 Feb 2016, 17:24 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

        J 1 Reply Last reply 19 Feb 2016, 17:58
        0
        • C clarity
          19 Feb 2016, 17:24

          @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

          J Offline
          J Offline
          jpnurmi
          wrote on 19 Feb 2016, 17:58 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 19 Feb 2016, 18:19
          0
          • J jpnurmi
            19 Feb 2016, 17:58

            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 19 Feb 2016, 18:19 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);
                            }
                        }
                    }
            
            J 1 Reply Last reply 19 Feb 2016, 18:21
            0
            • C clarity
              19 Feb 2016, 18:19

              @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);
                              }
                          }
                      }
              
              J Offline
              J Offline
              jpnurmi
              wrote on 19 Feb 2016, 18:21 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 19 Feb 2016, 18:24
              0
              • J jpnurmi
                19 Feb 2016, 18:21

                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 19 Feb 2016, 18:24 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;
                }

                J 1 Reply Last reply 19 Feb 2016, 18:31
                0
                • C clarity
                  19 Feb 2016, 18:24

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

                  J Offline
                  J Offline
                  jpnurmi
                  wrote on 19 Feb 2016, 18:31 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 19 Feb 2016, 18:39
                  0
                  • J jpnurmi
                    19 Feb 2016, 18:31

                    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 19 Feb 2016, 18:39 last edited by
                    #9

                    @jpnurmi said:

                    QAbstractListModel

                    That fixed it! Thank you so much!

                    1 Reply Last reply
                    0

                    9/9

                    19 Feb 2016, 18:39

                    • Login

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