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 with base and derived class
Forum Updated to NodeBB v4.3 + New Features

QAbstractListModel with base and derived class

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 125 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.
  • R Offline
    R Offline
    Redman
    wrote last edited by Redman
    #1

    Hi,

    class A {};
    
    class B : public A {};
    

    I implemented a QAbstractListModel for A. Now I need one for B.

    QVariant
    ClassBListModel::data(const QModelIndex& index, int role) const {
       // There is no data in the root element
       if (!index.isValid()) {
          return QVariant();
       }
       
       QVariant classAProperty = ClassAListModel::data(index,role);
       
       // Retrieved base property, return it
       if (!classAProperty .isNull()) {
    	return baseProperty;
       }
       
       // Requested role is part of classB property
       switch (role) {
          case ClassBRole1: {
             return QVariant::fromValue<QString>(m_data[index.row()]->classBRole1());
             break;
          }
        }
    }
    

    This is the approach I came up with. It's pretty simple. I just want to make sure it's qt-esque. Or is there another approach particularly designed for my needs?

    JonBJ 1 Reply Last reply
    0
    • R Offline
      R Offline
      Redman
      wrote last edited by
      #4

      I think I will go for the following approach:
      BaseListModel implements

      protected:
      QList<BaseClass*> m_data
      

      Aswell as all needed functions to work on the BaseClass.
      When needed, I will implement the DerivedListModel and all necessary functions. Calling the BaseListModel functions setData,data,delete... and what not accordingly.
      The insert implementation will only be used by the lowest implementation of the ListModel in the inheritance chain.
      By qobject_casting accordingly this approach should be fine. Decisively for this to work will be the correct usage of insert.

      Did I overlook anything?

      1 Reply Last reply
      0
      • R Redman

        Hi,

        class A {};
        
        class B : public A {};
        

        I implemented a QAbstractListModel for A. Now I need one for B.

        QVariant
        ClassBListModel::data(const QModelIndex& index, int role) const {
           // There is no data in the root element
           if (!index.isValid()) {
              return QVariant();
           }
           
           QVariant classAProperty = ClassAListModel::data(index,role);
           
           // Retrieved base property, return it
           if (!classAProperty .isNull()) {
        	return baseProperty;
           }
           
           // Requested role is part of classB property
           switch (role) {
              case ClassBRole1: {
                 return QVariant::fromValue<QString>(m_data[index.row()]->classBRole1());
                 break;
              }
            }
        }
        

        This is the approach I came up with. It's pretty simple. I just want to make sure it's qt-esque. Or is there another approach particularly designed for my needs?

        JonBJ Online
        JonBJ Online
        JonB
        wrote last edited by
        #2

        @Redman
        Hmm. A couple of comments.

        In your m_data[index.row()]->classBRole1(), is the m_data a member of class B or is it a (publicly exported) member of the base class A?

        If you are going distinguish by role whether data belongs to class A or class B then I would suggest changing the order of your testing:

           switch (role)
           {
              case ClassBRole1:
                 return m_data[index.row()]->classBRole1();
              default:
                 break;
            }
            return ClassAListModel::data(index,role);
        

        This would avoid doing two data lookups and would allow for a genuine null value in either case.

        As your code stands, I wonder how you would intend to deal with ClassBListModel::setData()? You would be in danger of making ClassA do the storage, which you probably don't want.

        If you maintain separate m_datas for each class you will have to duplicate code if you implement insert/delete rows etc.

        R 1 Reply Last reply
        0
        • JonBJ JonB

          @Redman
          Hmm. A couple of comments.

          In your m_data[index.row()]->classBRole1(), is the m_data a member of class B or is it a (publicly exported) member of the base class A?

          If you are going distinguish by role whether data belongs to class A or class B then I would suggest changing the order of your testing:

             switch (role)
             {
                case ClassBRole1:
                   return m_data[index.row()]->classBRole1();
                default:
                   break;
              }
              return ClassAListModel::data(index,role);
          

          This would avoid doing two data lookups and would allow for a genuine null value in either case.

          As your code stands, I wonder how you would intend to deal with ClassBListModel::setData()? You would be in danger of making ClassA do the storage, which you probably don't want.

          If you maintain separate m_datas for each class you will have to duplicate code if you implement insert/delete rows etc.

          R Offline
          R Offline
          Redman
          wrote last edited by
          #3

          @JonB said in QAbstractListModel with base and derived class:

          @Redman
          Hmm. A couple of comments.

          In your m_data[index.row()]->classBRole1(), is the m_data a member of class B or is it a (publicly exported) member of the base class A?

          Well, thats a good question. I'd assume that m_data should be the data from ClassBListModel. This leads to ClassAListModel not having access to data, hence not being able to provide the base class properties.

          Storing the data in ClassAListModel makes no sense to me in this scenario.

          If you are going distinguish by role whether data belongs to class A or class B then I would suggest changing the order of your testing:

             switch (role)
             {
                case ClassBRole1:
                   return m_data[index.row()]->classBRole1();
                default:
                   break;
              }
              return ClassAListModel::data(index,role);
          

          This would avoid doing two data lookups and would allow for a genuine null value in either case.

          I do not see the benefit here. Please elaborate. To me it looks the same, just switched positions of A and B property lookup.

          As your code stands, I wonder how you would intend to deal with ClassBListModel::setData()? You would be in danger of making ClassA do the storage, which you probably don't want.
          If you maintain separate m_datas for each class you will have to duplicate code if you implement insert/delete rows etc.

          Agreed. This approach comes with some pitfalls.

          Maybe to elaborate a bit further on the circumstances:
          Class B is not always implemented, hence the QAbstractListModel is not aswell. It is dependent on the project I am working on.

          So being able to use both approaches with the same api is desired.

          JonBJ 1 Reply Last reply
          0
          • R Offline
            R Offline
            Redman
            wrote last edited by
            #4

            I think I will go for the following approach:
            BaseListModel implements

            protected:
            QList<BaseClass*> m_data
            

            Aswell as all needed functions to work on the BaseClass.
            When needed, I will implement the DerivedListModel and all necessary functions. Calling the BaseListModel functions setData,data,delete... and what not accordingly.
            The insert implementation will only be used by the lowest implementation of the ListModel in the inheritance chain.
            By qobject_casting accordingly this approach should be fine. Decisively for this to work will be the correct usage of insert.

            Did I overlook anything?

            1 Reply Last reply
            0
            • R Redman

              @JonB said in QAbstractListModel with base and derived class:

              @Redman
              Hmm. A couple of comments.

              In your m_data[index.row()]->classBRole1(), is the m_data a member of class B or is it a (publicly exported) member of the base class A?

              Well, thats a good question. I'd assume that m_data should be the data from ClassBListModel. This leads to ClassAListModel not having access to data, hence not being able to provide the base class properties.

              Storing the data in ClassAListModel makes no sense to me in this scenario.

              If you are going distinguish by role whether data belongs to class A or class B then I would suggest changing the order of your testing:

                 switch (role)
                 {
                    case ClassBRole1:
                       return m_data[index.row()]->classBRole1();
                    default:
                       break;
                  }
                  return ClassAListModel::data(index,role);
              

              This would avoid doing two data lookups and would allow for a genuine null value in either case.

              I do not see the benefit here. Please elaborate. To me it looks the same, just switched positions of A and B property lookup.

              As your code stands, I wonder how you would intend to deal with ClassBListModel::setData()? You would be in danger of making ClassA do the storage, which you probably don't want.
              If you maintain separate m_datas for each class you will have to duplicate code if you implement insert/delete rows etc.

              Agreed. This approach comes with some pitfalls.

              Maybe to elaborate a bit further on the circumstances:
              Class B is not always implemented, hence the QAbstractListModel is not aswell. It is dependent on the project I am working on.

              So being able to use both approaches with the same api is desired.

              JonBJ Online
              JonBJ Online
              JonB
              wrote last edited by
              #5

              @Redman said in QAbstractListModel with base and derived class:

              I do not see the benefit here. Please elaborate. To me it looks the same, just switched positions of A and B property lookup.

              100% yes. And as I wrote as a consequence:

              This would avoid doing two data lookups and would allow for a genuine null value in either case.

              So two benefits :)

              1 Reply Last reply
              0
              • R Redman has marked this topic as solved

              • Login

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