Qt Forum

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

    How to substitute a QAbstractItemModel with a QList<double> role with a QML ListModel?

    QML and Qt Quick
    1
    1
    949
    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.
    • H
      hmuelner last edited by

      I have a model derived from QAbstractItemModel. One of the roles ("values") returns a QList<double> which should be interpreted according to the role "type".

      Here is the reduced header file:
      @struct MyRecord
      {
      MyRecord()
      : type()
      , values()
      {
      }
      MyRecord(QString type, const QList<double>& values)
      : type(type)
      , values(values)
      {
      }
      QString type;
      QList<double> values;
      };

      class MyModel : public QAbstractListModel
      {
      Q_OBJECT
      Q_PROPERTY (int count READ rowCount)
      public:
      MyModel();
      virtual ~MyModel();

      virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
      virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
      virtual Qt::ItemFlags flags(const QModelIndex & index) const;
      
      enum UserRoles { TypeRole = Qt::UserRole, ValuesRole};
      virtual QHash<int, QByteArray> roleNames() const;
      

      public slots:
      void clear();
      void update(int from, int to);
      void load(const std::vector<MyRecord>& records);
      QVariant getRole(int idx, QString rolename) const;

      @

      This is the data method:
      @QVariant MyModel::data( const QModelIndex & index, int role /= Qt::DisplayRole/ ) const
      {
      Q_D(const MyModel);
      if (!index.isValid()) {
      return QVariant();
      }
      int row = index.row();
      auto current = d->records[row];
      if (role == TypeRole) {
      return current.type;
      } else if (role == ValuesRole) {
      return QVariant::fromValue(current.values);
      }
      return QVariant();
      }
      @

      I use this model in a QML canvas:
      @onPaint: {
      var ctx = getContext('2d')
      // iterate over the model's elements
      for (var i = 0; i < myModel.count; i++)
      {
      var type = myModel.getRole(i, "type");
      var values = myModel.getRole(i,"values");
      switch(true) {
      case type === "Line":
      var a = values[0]
      var b = values[1]
      var c = values[2]
      // draw an "infinite" line defined by ax+by+c=0
      // ....
      break
      }
      }
      }
      @

      This works so far, but for testing I would like to substitute this model with a QML ListModel, something like this:
      @ ListModel {
      id: myModel
      function getRole(i, role) {
      return get(i)[role];
      }
      function getValue(i, j)
      {
      var obj = get(i).values;
      for (var item in obj) {
      console.log(JSON.stringify(item));
      }
      }

          ListElement {
              type:"Segment";
              values: [
                  ListElement {value: 135}, // start point x
                  ListElement {value: -7.63567}, // start point y
                  ListElement{value: 130}, // end point x
                  ListElement {value: -2.35309} // end point y
              ]
          }
          ListElement {
              type:"ArcSegment";
              values: [
                  ListElement {value: 20.5}, // center x
                  ListElement {value: 13.553}, // center y
                  ListElement{value: 20.5}, // radius
                  ListElement {value: 130.319}, // angle1 deg
                  ListElement {value: 180}, // angle2 deg
                  ListElement {value: 1} // Counterclockwise
              ]
          }
          ListElement {
              type:"Line"; // a*x  + b*x + c = 0
              values: [
                  ListElement {value: 0}, // a
                  ListElement {value: -20}, //b
                  ListElement{value: 300} //c
              ]
          }
          ListElement {
              type:"Angle";
              values: [
                  ListElement {value: 30.9543}, // p1 x
                  ListElement {value: 11.0152}, // p1 y
                  ListElement{value: 21.5405},  // p2 x
                  ListElement {value: 10.0152}, // p2 y
                  ListElement {value: 31.5405}, // center x
                  ListElement {value: 10.0152}  // center y
              ]
          }
          ListElement {
              type:"PolyLine";
              values: [
                  ListElement {value: 10.9543}, // p1 x
                  ListElement {value: 11.0152}, // p1 y
                  ListElement{value: 21.5405},  // p2 x
                  ListElement {value: 10.0152}, // p2 y
                  ListElement {value: 31.5405}, // p3 x
                  ListElement {value: 10.0152}  // p3 y
                  ListElement {value: 41.5405}, // p4 x
                  ListElement {value: 20.0152}  // p4 y
              ]
          }
      }
      

      @

      BUT: I could not find a way to access the C++ and the QML model in the same way in my Canvas.
      The "type" role was easy, but the variable length "values" role was impossible for me.

      Any ideas?

      Helmut Mülner

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