Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QAbstractListModel into QAbstractListModel
Forum Updated to NodeBB v4.3 + New Features

QAbstractListModel into QAbstractListModel

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 2.9k Views 1 Watching
  • 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.
  • RomanoFXR Offline
    RomanoFXR Offline
    RomanoFX
    wrote on last edited by RomanoFX
    #1

    Hi!

    I am trying to put a model into another.

    I have a simple class (channel) (get/set an integer)
    I do a class (screen) inherited from QAbstractListModel of (channel).
    And then, I would do QAbstractListModel of (screen)

    Header

    #ifndef PREVIEWSCREENMODEL_H
    #define PREVIEWSCREENMODEL_H
    
    #include <QAbstractListModel>
    
    class PreviewChannelItem
    {
    
    public:
        /*
        \fn Constructor
        */
        PreviewChannelItem(const int &ChannelIndex);
    
        /*
        \fn Setters
        */
        void setChannelIndex(QVariant ChannelIndex);
    
        /*
        \fn Getters
        */
        inline int ChannelIndex() const { return m_ChannelIndex; }
    
    private:
        int m_ChannelIndex;
    
    };
    
    class PreviewChannelItemList : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum PreviewChannelItemListRoles {
            ChannelIndexRole = Qt::UserRole+1,
        };
    
        PreviewChannelItemList(QObject *parent = 0);
    
        Q_INVOKABLE void append(const int &ChannelIndex);
    
        Q_INVOKABLE void insertRow(int index, const QVariant &ChannelIndex);
    
        Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const;
    
        QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    
        QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    
        bool setData(const QModelIndex &index, const QVariant &value, int role);
    
        Qt::ItemFlags flags(const QModelIndex &index) const;
    
    signals:
        void dataChanged();
    protected:
        QHash<int, QByteArray> roleNames() const;
    private:
        QList<PreviewChannelItem> m_previewChannelItem;
    };
    
    class PreviewScreenModel : public QAbstractListModel
    {
        Q_OBJECT
    public:
        enum PreviewScreenModelRoles {
            PreviewChannelListRole = Qt::UserRole+1,
        };
        PreviewScreenModel(QObject *parent = 0);
    
        Q_INVOKABLE void append();
    
        Q_INVOKABLE void insertRow(int index);
    
        Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const;
    
        QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    
        QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    
        bool setData(const QModelIndex &index, const QVariant &value, int role);
    
        Qt::ItemFlags flags(const QModelIndex &index) const;
    
        Q_INVOKABLE bool removeRow(const int index);
    
        Q_INVOKABLE QVariantMap get(int idx) const;
    
    signals:
        void dataChanged();
    protected:
        QHash<int, QByteArray> roleNames() const;
    private:
        QList<PreviewChannelItemList> m_previewChannelItemList;
    };
    
    #endif // PREVIEWSCREENMODEL_H
    
    

    Source

    #include "previewscreenmodel.h"
    //#include <QAbstractListModel>
    
    
    PreviewChannelItem::PreviewChannelItem(const int &ChannelIndex)
                                           : m_ChannelIndex(ChannelIndex)
    {
    }
    
    /*************** Setters *****************/
    
    void PreviewChannelItem::setChannelIndex(QVariant ChannelIndex)
    {
        m_ChannelIndex = ChannelIndex.toInt();
    }
    /*********** End of Setters ***************/
    
    
    
    PreviewChannelItemList::PreviewChannelItemList(QObject *parent)
                        : QAbstractListModel(parent)
    {
    }
    
    void PreviewChannelItemList::append(const int &ChannelIndex)
    {
        PreviewChannelItem previewChannelItem(ChannelIndex);
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_previewChannelItem << previewChannelItem;
        endInsertRows();
    }
    
    void PreviewChannelItemList::insertRow(int index, const QVariant &ChannelIndex)
    {
        PreviewChannelItem &previewChannelItem = m_previewChannelItem[index];
        beginInsertRows(QModelIndex(), index, index);
        previewChannelItem.setChannelIndex(ChannelIndex);
        endInsertRows();
    }
    
    
    int PreviewChannelItemList::rowCount(const QModelIndex & parent) const {
        Q_UNUSED(parent);
        return m_previewChannelItem.count();
    }
    
    QVariant PreviewChannelItemList::data(const QModelIndex & index, int role) const {
        if (index.row() < 0 || index.row() >= m_previewChannelItem.count())
            return QVariant();
    
        const PreviewChannelItem &previewChannelItem = m_previewChannelItem[index.row()];
        switch(role) {
        case ChannelIndexRole:
            return previewChannelItem.ChannelIndex();
        default:
            return QVariant();
        }
    }
    
    QVariant PreviewChannelItemList::headerData(int section, Qt::Orientation orientation, int role) const
    {
        if (role == Qt::DisplayRole)
        {
            if (orientation == Qt::Horizontal) {
                switch (section)
                {
                case 0:
                    return QString("first");
                case 1:
                    return QString("second");
                case 2:
                    return QString("third");
                }
            }
        }
        return QVariant();
    }
    
    bool PreviewChannelItemList::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (index.row() > 0 || index.row() <= m_previewChannelItem.count())
        {
            PreviewChannelItem &previewChannelItem = m_previewChannelItem[index.row()];
            switch(role) {
            case ChannelIndexRole:
                previewChannelItem.setChannelIndex(value);
                break;
            default:
                break;
            }
            emit dataChanged();
            return true;
        }
        return false;
    }
    
    Qt::ItemFlags PreviewChannelItemList::flags(const QModelIndex &index) const
    {
        return Qt::ItemIsEditable | QAbstractListModel::flags(index);
    }
    
    QHash<int, QByteArray> PreviewChannelItemList::roleNames() const {
        QHash<int, QByteArray> roles;
        roles[ChannelIndexRole] = "channelIndex";
        return roles;
    }
    
    
    PreviewScreenModel::PreviewScreenModel(QObject *parent)
        : QAbstractListModel(parent)
    {
    }
    
    void PreviewScreenModel::append()
    {
        PreviewChannelItemList previewChannelItemList;
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_previewChannelItemList << previewChannelItemList;
        endInsertRows();
    }
    
    void PreviewScreenModel::insertRow(int index)
    {
        PreviewChannelItemList &previewChannelItemList = m_previewChannelItemList[index];
        beginInsertRows(QModelIndex(), index, index);
        m_previewChannelItemList << previewChannelItemList;
        endInsertRows();
    }
    
    int PreviewScreenModel::rowCount(const QModelIndex & parent) const {
        Q_UNUSED(parent);
        return m_previewChannelItemList.count();
    }
    
    QVariant PreviewScreenModel::data(const QModelIndex & index, int role) const {
        if (index.row() < 0 || index.row() >= m_previewChannelItemList.count())
            return QVariant();
    
        const PreviewChannelItemList &previewChannelItemList = m_previewChannelItemList[index.row()];
        switch(role) {
        case PreviewChannelListRole:
            return &previewChannelItemList;
        default:
            return QVariant();
        }
    }
    
    QVariant PreviewScreenModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
        if (role == Qt::DisplayRole)
        {
            if (orientation == Qt::Horizontal) {
                switch (section)
                {
                case 0:
                    return QString("first");
                case 1:
                    return QString("second");
                case 2:
                    return QString("third");
                }
            }
        }
        return QVariant();
    }
    
    bool PreviewScreenModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (index.row() > 0 || index.row() <= m_previewChannelItemList.count())
        {
            PreviewChannelItemList &previewChannelItemList = m_previewChannelItemList[index.row()];
            switch(role) {
            case PreviewChannelListRole:
                //previewChannelItemList.setChannelIndex(value);
                break;
    
            default:
                break;
            }
            emit dataChanged();
            return true;
        }
        return false;
    }
    
    
    Qt::ItemFlags PreviewScreenModel::flags(const QModelIndex &index) const
    {
        return Qt::ItemIsEditable | QAbstractListModel::flags(index);
    }
    
    QHash<int, QByteArray> PreviewScreenModel::roleNames() const {
        QHash<int, QByteArray> roles;
        roles[PreviewChannelListRole] = "previewChannelList";
        return roles;
    }
    
    bool PreviewScreenModel::removeRow(const int index)
    {
        if (index > 0 || index <= m_previewChannelItemList.count())
        {
            beginRemoveRows(QModelIndex(), index, index);
            m_previewChannelItemList.removeAt(index);
            endRemoveRows();
            emit dataChanged();
            return true;
        }
        return false;
    }
    
    QVariantMap PreviewScreenModel::get(int idx) const {
      QVariantMap map;
      foreach(int k, roleNames().keys()) {
        map[roleNames().value(k)] = data(index(idx, 0), k);
      }
      return map;
    }
    
    

    For the moment, I got errors : call to implicitly-deleted copy constructor of 'PreviewChannelItemList'
    current->v = new T(reinterpret_cast<T>(src->v));
    ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    and other looks like that last one.
    Am I on the right way to do it?

    raven-worxR 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      From the the error, I'd say you are trying to pass a copy of your model which is not possible. See here for more information.

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

      1 Reply Last reply
      0
      • RomanoFXR Offline
        RomanoFXR Offline
        RomanoFX
        wrote on last edited by
        #3

        Thank you @SGaist

        After reading your document, I guess it is not possible to make an QAbstractListModel of another QAbstractListModel.

        1 Reply Last reply
        0
        • RomanoFXR RomanoFX

          Hi!

          I am trying to put a model into another.

          I have a simple class (channel) (get/set an integer)
          I do a class (screen) inherited from QAbstractListModel of (channel).
          And then, I would do QAbstractListModel of (screen)

          Header

          #ifndef PREVIEWSCREENMODEL_H
          #define PREVIEWSCREENMODEL_H
          
          #include <QAbstractListModel>
          
          class PreviewChannelItem
          {
          
          public:
              /*
              \fn Constructor
              */
              PreviewChannelItem(const int &ChannelIndex);
          
              /*
              \fn Setters
              */
              void setChannelIndex(QVariant ChannelIndex);
          
              /*
              \fn Getters
              */
              inline int ChannelIndex() const { return m_ChannelIndex; }
          
          private:
              int m_ChannelIndex;
          
          };
          
          class PreviewChannelItemList : public QAbstractListModel
          {
              Q_OBJECT
          public:
              enum PreviewChannelItemListRoles {
                  ChannelIndexRole = Qt::UserRole+1,
              };
          
              PreviewChannelItemList(QObject *parent = 0);
          
              Q_INVOKABLE void append(const int &ChannelIndex);
          
              Q_INVOKABLE void insertRow(int index, const QVariant &ChannelIndex);
          
              Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const;
          
              QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
          
              QVariant headerData(int section, Qt::Orientation orientation, int role) const;
          
              bool setData(const QModelIndex &index, const QVariant &value, int role);
          
              Qt::ItemFlags flags(const QModelIndex &index) const;
          
          signals:
              void dataChanged();
          protected:
              QHash<int, QByteArray> roleNames() const;
          private:
              QList<PreviewChannelItem> m_previewChannelItem;
          };
          
          class PreviewScreenModel : public QAbstractListModel
          {
              Q_OBJECT
          public:
              enum PreviewScreenModelRoles {
                  PreviewChannelListRole = Qt::UserRole+1,
              };
              PreviewScreenModel(QObject *parent = 0);
          
              Q_INVOKABLE void append();
          
              Q_INVOKABLE void insertRow(int index);
          
              Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const;
          
              QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
          
              QVariant headerData(int section, Qt::Orientation orientation, int role) const;
          
              bool setData(const QModelIndex &index, const QVariant &value, int role);
          
              Qt::ItemFlags flags(const QModelIndex &index) const;
          
              Q_INVOKABLE bool removeRow(const int index);
          
              Q_INVOKABLE QVariantMap get(int idx) const;
          
          signals:
              void dataChanged();
          protected:
              QHash<int, QByteArray> roleNames() const;
          private:
              QList<PreviewChannelItemList> m_previewChannelItemList;
          };
          
          #endif // PREVIEWSCREENMODEL_H
          
          

          Source

          #include "previewscreenmodel.h"
          //#include <QAbstractListModel>
          
          
          PreviewChannelItem::PreviewChannelItem(const int &ChannelIndex)
                                                 : m_ChannelIndex(ChannelIndex)
          {
          }
          
          /*************** Setters *****************/
          
          void PreviewChannelItem::setChannelIndex(QVariant ChannelIndex)
          {
              m_ChannelIndex = ChannelIndex.toInt();
          }
          /*********** End of Setters ***************/
          
          
          
          PreviewChannelItemList::PreviewChannelItemList(QObject *parent)
                              : QAbstractListModel(parent)
          {
          }
          
          void PreviewChannelItemList::append(const int &ChannelIndex)
          {
              PreviewChannelItem previewChannelItem(ChannelIndex);
              beginInsertRows(QModelIndex(), rowCount(), rowCount());
              m_previewChannelItem << previewChannelItem;
              endInsertRows();
          }
          
          void PreviewChannelItemList::insertRow(int index, const QVariant &ChannelIndex)
          {
              PreviewChannelItem &previewChannelItem = m_previewChannelItem[index];
              beginInsertRows(QModelIndex(), index, index);
              previewChannelItem.setChannelIndex(ChannelIndex);
              endInsertRows();
          }
          
          
          int PreviewChannelItemList::rowCount(const QModelIndex & parent) const {
              Q_UNUSED(parent);
              return m_previewChannelItem.count();
          }
          
          QVariant PreviewChannelItemList::data(const QModelIndex & index, int role) const {
              if (index.row() < 0 || index.row() >= m_previewChannelItem.count())
                  return QVariant();
          
              const PreviewChannelItem &previewChannelItem = m_previewChannelItem[index.row()];
              switch(role) {
              case ChannelIndexRole:
                  return previewChannelItem.ChannelIndex();
              default:
                  return QVariant();
              }
          }
          
          QVariant PreviewChannelItemList::headerData(int section, Qt::Orientation orientation, int role) const
          {
              if (role == Qt::DisplayRole)
              {
                  if (orientation == Qt::Horizontal) {
                      switch (section)
                      {
                      case 0:
                          return QString("first");
                      case 1:
                          return QString("second");
                      case 2:
                          return QString("third");
                      }
                  }
              }
              return QVariant();
          }
          
          bool PreviewChannelItemList::setData(const QModelIndex &index, const QVariant &value, int role)
          {
              if (index.row() > 0 || index.row() <= m_previewChannelItem.count())
              {
                  PreviewChannelItem &previewChannelItem = m_previewChannelItem[index.row()];
                  switch(role) {
                  case ChannelIndexRole:
                      previewChannelItem.setChannelIndex(value);
                      break;
                  default:
                      break;
                  }
                  emit dataChanged();
                  return true;
              }
              return false;
          }
          
          Qt::ItemFlags PreviewChannelItemList::flags(const QModelIndex &index) const
          {
              return Qt::ItemIsEditable | QAbstractListModel::flags(index);
          }
          
          QHash<int, QByteArray> PreviewChannelItemList::roleNames() const {
              QHash<int, QByteArray> roles;
              roles[ChannelIndexRole] = "channelIndex";
              return roles;
          }
          
          
          PreviewScreenModel::PreviewScreenModel(QObject *parent)
              : QAbstractListModel(parent)
          {
          }
          
          void PreviewScreenModel::append()
          {
              PreviewChannelItemList previewChannelItemList;
              beginInsertRows(QModelIndex(), rowCount(), rowCount());
              m_previewChannelItemList << previewChannelItemList;
              endInsertRows();
          }
          
          void PreviewScreenModel::insertRow(int index)
          {
              PreviewChannelItemList &previewChannelItemList = m_previewChannelItemList[index];
              beginInsertRows(QModelIndex(), index, index);
              m_previewChannelItemList << previewChannelItemList;
              endInsertRows();
          }
          
          int PreviewScreenModel::rowCount(const QModelIndex & parent) const {
              Q_UNUSED(parent);
              return m_previewChannelItemList.count();
          }
          
          QVariant PreviewScreenModel::data(const QModelIndex & index, int role) const {
              if (index.row() < 0 || index.row() >= m_previewChannelItemList.count())
                  return QVariant();
          
              const PreviewChannelItemList &previewChannelItemList = m_previewChannelItemList[index.row()];
              switch(role) {
              case PreviewChannelListRole:
                  return &previewChannelItemList;
              default:
                  return QVariant();
              }
          }
          
          QVariant PreviewScreenModel::headerData(int section, Qt::Orientation orientation, int role) const
          {
              if (role == Qt::DisplayRole)
              {
                  if (orientation == Qt::Horizontal) {
                      switch (section)
                      {
                      case 0:
                          return QString("first");
                      case 1:
                          return QString("second");
                      case 2:
                          return QString("third");
                      }
                  }
              }
              return QVariant();
          }
          
          bool PreviewScreenModel::setData(const QModelIndex &index, const QVariant &value, int role)
          {
              if (index.row() > 0 || index.row() <= m_previewChannelItemList.count())
              {
                  PreviewChannelItemList &previewChannelItemList = m_previewChannelItemList[index.row()];
                  switch(role) {
                  case PreviewChannelListRole:
                      //previewChannelItemList.setChannelIndex(value);
                      break;
          
                  default:
                      break;
                  }
                  emit dataChanged();
                  return true;
              }
              return false;
          }
          
          
          Qt::ItemFlags PreviewScreenModel::flags(const QModelIndex &index) const
          {
              return Qt::ItemIsEditable | QAbstractListModel::flags(index);
          }
          
          QHash<int, QByteArray> PreviewScreenModel::roleNames() const {
              QHash<int, QByteArray> roles;
              roles[PreviewChannelListRole] = "previewChannelList";
              return roles;
          }
          
          bool PreviewScreenModel::removeRow(const int index)
          {
              if (index > 0 || index <= m_previewChannelItemList.count())
              {
                  beginRemoveRows(QModelIndex(), index, index);
                  m_previewChannelItemList.removeAt(index);
                  endRemoveRows();
                  emit dataChanged();
                  return true;
              }
              return false;
          }
          
          QVariantMap PreviewScreenModel::get(int idx) const {
            QVariantMap map;
            foreach(int k, roleNames().keys()) {
              map[roleNames().value(k)] = data(index(idx, 0), k);
            }
            return map;
          }
          
          

          For the moment, I got errors : call to implicitly-deleted copy constructor of 'PreviewChannelItemList'
          current->v = new T(reinterpret_cast<T>(src->v));
          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          and other looks like that last one.
          Am I on the right way to do it?

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @RomanoFX
          beside i do not understanding what you trying to achieve yet, the posted error line doesn't even occur in the code you've posted?

          Maybe you can explain more clearly what you want to do with those 2 models.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • RomanoFXR Offline
            RomanoFXR Offline
            RomanoFX
            wrote on last edited by RomanoFX
            #5

            Thank you for your answer and sorry for bad explanations I gave.

            I have a Channel class (only integer)
            ScreenModel is a QList<Channel> based on QAbstractListModel.
            This is working on QML side in a delegate.

            I would create a new model ContainerModel as QList<ScreenModel> and use it as delegate on QML side.

            In QML side, it would be great to do :

             ListView {
                    model: ContainerModel
                    
                    delegate: ListView {
                        model: ScreenModel
                        delegate: Text{
                            text: channel
                        }
                    }
                }
                
            

            If I am still not clear, I can explain the result I would.

            Thank you for your help

            raven-worxR 1 Reply Last reply
            0
            • RomanoFXR RomanoFX

              Thank you for your answer and sorry for bad explanations I gave.

              I have a Channel class (only integer)
              ScreenModel is a QList<Channel> based on QAbstractListModel.
              This is working on QML side in a delegate.

              I would create a new model ContainerModel as QList<ScreenModel> and use it as delegate on QML side.

              In QML side, it would be great to do :

               ListView {
                      model: ContainerModel
                      
                      delegate: ListView {
                          model: ScreenModel
                          delegate: Text{
                              text: channel
                          }
                      }
                  }
                  
              

              If I am still not clear, I can explain the result I would.

              Thank you for your help

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              @RomanoFX
              so basically you want to create a tree-model out of 2 list model classes?
              You would need to implement a custom QAbstractProxyModel and map the (tree-like) indexes to the correct (sub-)model.

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              1
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #7

                isn't a list of lists just a list?

                I think what you want is just a tree model/view

                Edit:
                I was late on the answer.
                In C++ it's very easy as you have QAbstractItemView::setRootIndex you'll have to implement something similar in QML. what I suspect though is that delegate will be very slow if the number of items is high

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                raven-worxR 1 Reply Last reply
                1
                • VRoninV VRonin

                  isn't a list of lists just a list?

                  I think what you want is just a tree model/view

                  Edit:
                  I was late on the answer.
                  In C++ it's very easy as you have QAbstractItemView::setRootIndex you'll have to implement something similar in QML. what I suspect though is that delegate will be very slow if the number of items is high

                  raven-worxR Offline
                  raven-worxR Offline
                  raven-worx
                  Moderators
                  wrote on last edited by raven-worx
                  #8

                  @VRonin said in QAbstractListModel into QAbstractListModel:

                  isn't a list of lists just a list?

                  depends it you want it "flat" or not. If you still need to distinguish the origin of each (flattened) list element you need a tree structure.

                  Edit: ok not necessarily, since you could provide a custom data role to do so...
                  Anyway you need to merge your models into single one with a proxy model. If you decide for a tree structure then your root indexes have child indexes. For a flat approach they dont.

                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                  If you have a question please use the forum so others can benefit from the solution in the future

                  1 Reply Last reply
                  2

                  • Login

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