Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Unsolved returning objects from roles

    QML and Qt Quick
    qt-quick qml models roles
    4
    10
    2419
    Loading More Posts
    • 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
      clarity last edited by SGaist

      Hey,

      I'm trying to get a role to return an object. I'm running into undefined errors when I try to access display.blockNumber and display.time

      here's my code

      blockdisplay.h:

      #ifndef BLOCKDISPLAY_H
      #define BLOCKDISPLAY_H
      
      #include <QMetaType>
      
      class BlockDisplay
      {
      public:
          BlockDisplay();
          BlockDisplay(int blocknum, long time);
          BlockDisplay(const BlockDisplay &other);
      
          int blockNumber() const;
          long time() const;
      
      private:
          int m_blocknumber;
          long m_time;
      };
      
      Q_DECLARE_METATYPE(BlockDisplay)
      
      #endif // BLOCKDISPLAY_H
      

      blockdisplay.cpp:

      #include "blockdisplay.h"
      
      
      BlockDisplay::BlockDisplay() {
      
      }
      
      BlockDisplay::BlockDisplay(int blocknum, long time) {
          this->m_blocknumber = blocknum;
          this->m_time = time;
      }
      
      BlockDisplay::BlockDisplay(const BlockDisplay &other) {
          this->m_blocknumber = other.blockNumber();
          this->m_time = other.time();
      }
      
      
      int BlockDisplay::blockNumber() const {
          return this->m_blocknumber;
      }
      
      long BlockDisplay::time() const {
          return this->m_time;
      }
      

      modelclass.h:

      #ifndef MODELCLASS_H
      #define MODELCLASS_H
      
      #include <QObject>
      #include <QAbstractListModel>
      #include <QStringListModel>
      
      #include <blockchain.h>
      
      class ModelClass : public QAbstractListModel
      {
          Q_OBJECT
      
          Q_PROPERTY(qint32 blockheight READ blockheight)
      
      protected:
          Blockchain bc{};
          int first;
      public:
          ModelClass();
          qint32 blockheight();
          void init();
      
          int rowCount(const QModelIndex &parent = QModelIndex()) const;
          QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
      };
      
      #endif // MODELCLASS_H
      

      modelclass.cpp:

      #include "modelclass.h"
      
      #include <string.h>
      #include <qdebug>
      
      #include "blockdisplay.h"
      
      using namespace std;
      
      ModelClass::ModelClass()
      {
      
      }
      
      void ModelClass::init() {
          bc.init();
          if ( !bc.Valid() )
              qDebug() << "invalid";
          else {
              bc.SeekToFirst();
              bc.Next();
              if ( !bc.Valid() )
                  qDebug() << "invalid";
              else
                  first = bc.GetCurrentBlock().signedhead().head().num();
          }
      
          //setProperty("blockheight",bc.GetBlockHeight());
      }
      
      qint32 ModelClass::blockheight() {
          return bc.GetBlockHeight();
      }
      
      int ModelClass::rowCount(const QModelIndex &parent) const {
          //qInfo() << " 0test " << bc.GetBlockHeight();
      
          return bc.GetBlockHeight() - first;
      }
      
      QVariant ModelClass::data(const QModelIndex & index, int role) const {
          qInfo() << " 1test " << index;
          int row = bc.GetBlockHeight() - index.row();// + 1 + first;
          if (index.isValid()) {
      
              bc.Seek(row);
      
              if (bc.Valid()) {
                  if (role == Qt::DisplayRole) {
                      int blocknum = bc.GetCurrentBlock().signedhead().head().num();
                      long timestamp = bc.GetCurrentBlock().signedhead().head().timestamp();
      
                      BlockDisplay dsply{blocknum, timestamp};
                      QVariant var;
                      var.setValue(dsply);
                      return var;
                  }
              }
          }
      
          return QVariant();
      }
      

      snippet from blocks.qml:

          Component {
              id: gridComp
              Row {
                  Text {
                      text: display.blockNumber + " "
      
                      MouseArea {
                          anchors.fill: parent
                          onClicked: {
                              list.currentIndex = index;
                              ld.setSource("detail.qml")
                          }
                      }
                  }
                  Text {
                      text: display.time + " "
                  }
              }
          }
      

      [edit: fixed missing coding tags SGaist]

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        You should take a look at the Using C++ Models with Qt Quick Views chapter of Qt's documentation. It should get you started.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        C 1 Reply Last reply Reply Quote 0
        • C
          clarity @SGaist last edited by

          @SGaist I'm a little confused. Perhaps I'm going in the wrong direction. All of the examples I've seen use roles with one value for example QString. I was thinking I can return an object and access it's properties via display.propertyname. Is this even possible?

          Thanks!

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            If you take the QObjectList based example you'll see that you can access your object properties.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            C 1 Reply Last reply Reply Quote 0
            • C
              clarity @SGaist last edited by

              @SGaist First of all, thanks for all of your help. I still have a question though. Do you have to use the QObjectList to access your object properties or is this possible through QAbstractListModel?

              jpnurmi 1 Reply Last reply Reply Quote 0
              • jpnurmi
                jpnurmi @clarity last edited by

                @clarity Sure, you can also return QObjects from QAbstractListModel::data().

                1 Reply Last reply Reply Quote 0
                • ekkescorner
                  ekkescorner Qt Champions 2016 last edited by

                  @jpnurmi from docs I read that I can use a list of QObject* as model data, but this model doesn't know if list content changes I have to reset the model. haven't tested yet but doesn't sound flexible.
                  In BlackBerry Cascades implementation I can fill a data model with a list of QObject* and use the properties of QObject* data classes in list view items. editing properties in QML the C++ QObject* was changed and changes automatically proposed to QML. very convenient: have a list, tap on row, push details page, change values, pop page and list values are automagically also changed.
                  ...reading through the docs and examples to find out how to do this with Qt 5.6 ... landing in this thread.
                  from your answer I have the hope that there's a way to deal with QObject* data from C++ in QML, but perhaps I misunderstood.

                  ekke
                  Qt Champion
                  mobile business apps
                  Qt Quick Controls 2 (Material style) for Android / iOS

                  jpnurmi 1 Reply Last reply Reply Quote 0
                  • jpnurmi
                    jpnurmi @ekkescorner last edited by

                    @ekkescorner QObjectList is indeed not great for dynamic lists, because there's no way to monitor for changes. Here's a dummy example of using QAbstractListModel + QObject:

                    // main.cpp
                    #include <QtGui>
                    #include <QtQml>
                    
                    class ExampleModel : public QAbstractListModel
                    {
                        Q_OBJECT
                    
                    public:
                        ExampleModel(QObject *parent = 0) : QAbstractListModel(parent)
                        {
                            for (int i = 0; i < 10; ++i) {
                                QObject *object = new QObject(this);
                                object->setObjectName(QString::number(i) + QString::number(i));
                                m_objects.append(object);
                            }
                        }
                    
                        int rowCount(const QModelIndex &parent) const
                        {
                            if (parent.isValid())
                                return 0;
                    
                            return m_objects.count();
                        }
                    
                        QVariant data(const QModelIndex &index, int role) const
                        {
                            if (!index.isValid() || role != Qt::UserRole)
                                return QVariant();
                    
                            return QVariant::fromValue(m_objects.at(index.row()));
                        }
                    
                        QHash<int, QByteArray> roleNames() const
                        {
                            QHash<int, QByteArray> roles;
                            roles.insert(Qt::UserRole, "example");
                            return roles;
                        }
                    
                    private:
                        QObjectList m_objects;
                    };
                    
                    int main(int argc, char *argv[])
                    {
                        QGuiApplication app(argc, argv);
                    
                        qmlRegisterType<ExampleModel>("example", 1, 0, "ExampleModel");
                    
                        QQmlApplicationEngine engine;
                        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                    
                        return app.exec();
                    }
                    
                    #include "main.moc"
                    
                    // main.qml
                    import QtQuick 2.5
                    import QtQuick.Window 2.2
                    import example 1.0
                    
                    Window {
                        visible: true
                    
                        ListView {
                            spacing: 20
                            anchors.fill: parent
                            model: ExampleModel { }
                            delegate: Text {
                                text: example.objectName
                            }
                        }
                    }
                    
                    ekkescorner 1 Reply Last reply Reply Quote 1
                    • ekkescorner
                      ekkescorner Qt Champions 2016 last edited by

                      @jpnurmi thanks. sounds great - will try it out soon.

                      ekke
                      Qt Champion
                      mobile business apps
                      Qt Quick Controls 2 (Material style) for Android / iOS

                      1 Reply Last reply Reply Quote 0
                      • ekkescorner
                        ekkescorner Qt Champions 2016 @jpnurmi last edited by

                        @jpnurmi cool :)
                        did some first tests with QAbstractListModel filled with some Customer* (QObject)
                        inserted customers, removed customers, changed properties via C++
                        all correct refreshed in QML ListView

                        seems I can "port" most of my data model logic / UI from BlackBerry Cascades to Qt 5.6 :)

                        ekke
                        Qt Champion
                        mobile business apps
                        Qt Quick Controls 2 (Material style) for Android / iOS

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post