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. Software development challenges around index creation for data models

Software development challenges around index creation for data models

Scheduled Pinned Locked Moved Unsolved General and Desktop
data modelssoftware designindex creationalgorithmsintegers
26 Posts 3 Posters 6.2k 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.
  • V VRonin
    9 Oct 2018, 09:42

    @elfring said in Software development challenges around index creation for data models:

    I imagine that an index value can be computed for a simple hierarchical model by using a formula like “((X & 0x0FFF) << 16) + (Y & 0xFFFF)”

    In some specific cases yes but not in general

    I hope that this software situation can be improved somehow.

    Nope. The concept is very similar to how xml DOM works so it's a solid design pattern that doesn't need changing. not intuitive != wrong.

    E Offline
    E Offline
    elfring
    wrote on 9 Oct 2018, 10:35 last edited by
    #5

    it's a solid design pattern

    Index usage can be generally fine.

    that doesn't need changing. not intuitive != wrong.

    • Can the desired index calculations become easier to reuse for customised data models?
    • Would you like to offer any known indexing approaches directly?
    V 1 Reply Last reply 9 Oct 2018, 10:48
    0
    • E elfring
      9 Oct 2018, 10:35

      it's a solid design pattern

      Index usage can be generally fine.

      that doesn't need changing. not intuitive != wrong.

      • Can the desired index calculations become easier to reuse for customised data models?
      • Would you like to offer any known indexing approaches directly?
      V Offline
      V Offline
      VRonin
      wrote on 9 Oct 2018, 10:48 last edited by
      #6

      @elfring said in Software development challenges around index creation for data models:

      Would you like to offer any known indexing approaches directly?

      struct ModelItem{
      ModelItem* parent = nullptr;
      QList<QList<ModelItem*> > children;
      QMap<int,QVariant> data;
      }
      

      "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

      E 1 Reply Last reply 9 Oct 2018, 11:07
      0
      • V VRonin
        9 Oct 2018, 10:48

        @elfring said in Software development challenges around index creation for data models:

        Would you like to offer any known indexing approaches directly?

        struct ModelItem{
        ModelItem* parent = nullptr;
        QList<QList<ModelItem*> > children;
        QMap<int,QVariant> data;
        }
        
        E Offline
        E Offline
        elfring
        wrote on 9 Oct 2018, 11:07 last edited by
        #7

        struct ModelItem{

        You have shown another example for a data structure. Which implementation would you choose for the index computation then with the corresponding customised hierarchical data model?

        V 1 Reply Last reply 9 Oct 2018, 20:16
        0
        • V VRonin
          9 Oct 2018, 08:39

          @elfring said in Software development challenges around index creation for data models:

          This technical detail can trigger software development considerations for the portable value range of signed integers.

          Yes but not really. Qt only supports platforms where int is 4 bytes of 8 bits

          Smaller components can be combined into the integer data type for the final index usage.

          What do you have in mind?

          I find this API not so obvious for the implementation

          I agree it's not intuitive but once you get accustomed to it it works fine.

          E Offline
          E Offline
          elfring
          wrote on 9 Oct 2018, 18:55 last edited by
          #8

          … but once you get accustomed to it it works fine.

          Have you found any information sources where developers shared more of their experiences with customised (hierarchical) data models?

          1 Reply Last reply
          0
          • E elfring
            9 Oct 2018, 11:07

            struct ModelItem{

            You have shown another example for a data structure. Which implementation would you choose for the index computation then with the corresponding customised hierarchical data model?

            V Offline
            V Offline
            VRonin
            wrote on 9 Oct 2018, 20:16 last edited by
            #9

            @elfring said in Software development challenges around index creation for data models:

            You have shown another example for a data structure.

            No, that is a hierarchical level. Something like the below:

            UNTESTED CODE!

            class GenericModel : public QAbstractItemModel{
                Q_DISABLE_COPY(GenericModel)
                struct ModelItem{
                    ModelItem* parent = nullptr;
                    QVector<QVector<ModelItem*> > children;
                    QMap<int,QVariant> data;
                    ModelItem(ModelItem* par)
                        :parent(par)
                    {}
                    ~ModelItem(){
                        for(auto i=children.begin();i!=children.end();++i){
                            for(auto j=i->begin();j!=i->end();++j)
                                delete *j;
                        }
                    }
                };
            public:
                explicit GenericModel(QObject* parent = nullptr)
                    : QAbstractItemModel(parent)
                    , rootItem(new ModelItem(nullptr))
                {}
                ~GenericModel() { delete rootItem;}
                QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override{
                    Q_ASSERT(checkIndex(parent));
                    if(parent.isValid())
                        return createIndex(row,column,itemForIndex(parent));
                    return createIndex(row,column, rootItem);
                }
                QModelIndex parent(const QModelIndex &index) const override{
                    Q_ASSERT(checkIndex(index, CheckIndexOption::DoNotUseParent));
                    return indexForItem(static_cast<ModelItem*>(index.internalPointer()));
                }
                int rowCount(const QModelIndex &parent = QModelIndex()) const override{
                    Q_ASSERT(checkIndex(parent));
                    if(!parent.isValid())
                        return rootItem->children.size();
                    return itemForIndex(parent)->children.size();
                }
                int columnCount(const QModelIndex &parent = QModelIndex()) const override{
                    Q_ASSERT(checkIndex(parent));
                    const ModelItem* const item =parent.isValid() ? itemForIndex(parent) : rootItem;
                    Q_ASSERT(item);
                    if(item->children.isEmpty())
                        return 0;
                    return item->children.at(0).size();
                }
                QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{
                    Q_ASSERT(checkIndex(index));
                    const ModelItem* const item = itemForIndex(index);
                    if(!item)
                        return QVariant();
                    return item->data.value(role);
                }
                bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override{
                    Q_ASSERT(checkIndex(index));
                    ModelItem* const item = itemForIndex(index);
                    if(!item)
                        return false;
                    //inefficient but works
                    item->data[role] = value;
                    dataChanged(index,index,{role});
                    return true;
                }
                bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override{
                    if(row<0 || row>rowCount(parent) || count<=0)
                        return false;
                    ModelItem* const parItem = parent.isValid() ? itemForIndex(parent) : rootItem;
                    const int colCount = columnCount(parent);
                    beginInsertRows(parent,row,row+count-1);
                    while(count--){
                        QVector<ModelItem*> colVector(colCount);
                        for(int i=0;i<colCount;++i)
                            colVector[i]=new ModelItem(parItem);
                        parItem->children.insert(row, colVector);
                    }
                    endInsertRows();
                    return true;
                }
                bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override{
                    if(column<0 || column>columnCount(parent) || count<=0)
                        return false;
                    ModelItem* const parItem = parent.isValid() ? itemForIndex(parent) : rootItem;
                    const int rowCnt = rowCount(parent);
                    if(rowCnt==0)
                        return false; //can't insert columns if no rows are there
                    beginInsertColumns(parent,column,column+count-1);
                    while(count--){
                        for(int i=0;i<rowCnt;++i)
                            parItem->children[i].insert(column, new ModelItem(parItem));
                    }
                    endInsertColumns();
                    return true;
                }
            private:
                ModelItem* itemForIndex(const QModelIndex& idx) const {
                    if(!checkIndex(idx, CheckIndexOption::IndexIsValid))
                        return nullptr;
                    const ModelItem* const parentItem = static_cast<ModelItem*>(idx.internalPointer());
                    return parentItem->children.at(idx.row()).at(idx.column());
                }
                QModelIndex indexForItem(const ModelItem* const itm) const {
                    ModelItem* const parentItem = itm->parent;
                    if(!parentItem)
                        return QModelIndex();
                    for(int rowIter = 0, maxRow = parentItem->children.size(); rowIter<maxRow;++rowIter){
                        for(int colIter = 0, maxCol = parentItem->children.at(rowIter).size(); colIter<maxCol;++colIter){
                            if(parentItem->children.at(rowIter).at(colIter) == itm)
                                return createIndex(rowIter,colIter,parentItem);
                        }
                    }
                    Q_UNREACHABLE();
                    return QModelIndex();
                }
                ModelItem* rootItem;
            };
            

            "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

            E 1 Reply Last reply 9 Oct 2018, 20:40
            2
            • V VRonin
              9 Oct 2018, 20:16

              @elfring said in Software development challenges around index creation for data models:

              You have shown another example for a data structure.

              No, that is a hierarchical level. Something like the below:

              UNTESTED CODE!

              class GenericModel : public QAbstractItemModel{
                  Q_DISABLE_COPY(GenericModel)
                  struct ModelItem{
                      ModelItem* parent = nullptr;
                      QVector<QVector<ModelItem*> > children;
                      QMap<int,QVariant> data;
                      ModelItem(ModelItem* par)
                          :parent(par)
                      {}
                      ~ModelItem(){
                          for(auto i=children.begin();i!=children.end();++i){
                              for(auto j=i->begin();j!=i->end();++j)
                                  delete *j;
                          }
                      }
                  };
              public:
                  explicit GenericModel(QObject* parent = nullptr)
                      : QAbstractItemModel(parent)
                      , rootItem(new ModelItem(nullptr))
                  {}
                  ~GenericModel() { delete rootItem;}
                  QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override{
                      Q_ASSERT(checkIndex(parent));
                      if(parent.isValid())
                          return createIndex(row,column,itemForIndex(parent));
                      return createIndex(row,column, rootItem);
                  }
                  QModelIndex parent(const QModelIndex &index) const override{
                      Q_ASSERT(checkIndex(index, CheckIndexOption::DoNotUseParent));
                      return indexForItem(static_cast<ModelItem*>(index.internalPointer()));
                  }
                  int rowCount(const QModelIndex &parent = QModelIndex()) const override{
                      Q_ASSERT(checkIndex(parent));
                      if(!parent.isValid())
                          return rootItem->children.size();
                      return itemForIndex(parent)->children.size();
                  }
                  int columnCount(const QModelIndex &parent = QModelIndex()) const override{
                      Q_ASSERT(checkIndex(parent));
                      const ModelItem* const item =parent.isValid() ? itemForIndex(parent) : rootItem;
                      Q_ASSERT(item);
                      if(item->children.isEmpty())
                          return 0;
                      return item->children.at(0).size();
                  }
                  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{
                      Q_ASSERT(checkIndex(index));
                      const ModelItem* const item = itemForIndex(index);
                      if(!item)
                          return QVariant();
                      return item->data.value(role);
                  }
                  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override{
                      Q_ASSERT(checkIndex(index));
                      ModelItem* const item = itemForIndex(index);
                      if(!item)
                          return false;
                      //inefficient but works
                      item->data[role] = value;
                      dataChanged(index,index,{role});
                      return true;
                  }
                  bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override{
                      if(row<0 || row>rowCount(parent) || count<=0)
                          return false;
                      ModelItem* const parItem = parent.isValid() ? itemForIndex(parent) : rootItem;
                      const int colCount = columnCount(parent);
                      beginInsertRows(parent,row,row+count-1);
                      while(count--){
                          QVector<ModelItem*> colVector(colCount);
                          for(int i=0;i<colCount;++i)
                              colVector[i]=new ModelItem(parItem);
                          parItem->children.insert(row, colVector);
                      }
                      endInsertRows();
                      return true;
                  }
                  bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override{
                      if(column<0 || column>columnCount(parent) || count<=0)
                          return false;
                      ModelItem* const parItem = parent.isValid() ? itemForIndex(parent) : rootItem;
                      const int rowCnt = rowCount(parent);
                      if(rowCnt==0)
                          return false; //can't insert columns if no rows are there
                      beginInsertColumns(parent,column,column+count-1);
                      while(count--){
                          for(int i=0;i<rowCnt;++i)
                              parItem->children[i].insert(column, new ModelItem(parItem));
                      }
                      endInsertColumns();
                      return true;
                  }
              private:
                  ModelItem* itemForIndex(const QModelIndex& idx) const {
                      if(!checkIndex(idx, CheckIndexOption::IndexIsValid))
                          return nullptr;
                      const ModelItem* const parentItem = static_cast<ModelItem*>(idx.internalPointer());
                      return parentItem->children.at(idx.row()).at(idx.column());
                  }
                  QModelIndex indexForItem(const ModelItem* const itm) const {
                      ModelItem* const parentItem = itm->parent;
                      if(!parentItem)
                          return QModelIndex();
                      for(int rowIter = 0, maxRow = parentItem->children.size(); rowIter<maxRow;++rowIter){
                          for(int colIter = 0, maxCol = parentItem->children.at(rowIter).size(); colIter<maxCol;++colIter){
                              if(parentItem->children.at(rowIter).at(colIter) == itm)
                                  return createIndex(rowIter,colIter,parentItem);
                          }
                      }
                      Q_UNREACHABLE();
                      return QModelIndex();
                  }
                  ModelItem* rootItem;
              };
              
              E Offline
              E Offline
              elfring
              wrote on 9 Oct 2018, 20:40 last edited by
              #10

              that is a hierarchical level.

              Do you distinguish any levels in the object hierarchy of a data model?

              Something like the below:

              This source code example looks also interesting.

              V 1 Reply Last reply 10 Oct 2018, 06:28
              0
              • E elfring
                9 Oct 2018, 20:40

                that is a hierarchical level.

                Do you distinguish any levels in the object hierarchy of a data model?

                Something like the below:

                This source code example looks also interesting.

                V Offline
                V Offline
                VRonin
                wrote on 10 Oct 2018, 06:28 last edited by
                #11

                @elfring said in Software development challenges around index creation for data models:

                Do you distinguish any levels in the object hierarchy of a data model?

                You can if you want. Instead of making ModelItem a struct, use it as an interface and subclass it to create different type of items if you need

                "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

                E 1 Reply Last reply 10 Oct 2018, 07:12
                0
                • V VRonin
                  10 Oct 2018, 06:28

                  @elfring said in Software development challenges around index creation for data models:

                  Do you distinguish any levels in the object hierarchy of a data model?

                  You can if you want. Instead of making ModelItem a struct, use it as an interface and subclass it to create different type of items if you need

                  E Offline
                  E Offline
                  elfring
                  wrote on 10 Oct 2018, 07:12 last edited by
                  #12

                  You can if you want.

                  How would you map a data model to Qt programming interfaces when each level within a hierarchy should correspond to a specific class?

                  K V 2 Replies Last reply 10 Oct 2018, 09:01
                  0
                  • E elfring
                    10 Oct 2018, 07:12

                    You can if you want.

                    How would you map a data model to Qt programming interfaces when each level within a hierarchy should correspond to a specific class?

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 10 Oct 2018, 09:01 last edited by
                    #13

                    @elfring said in Software development challenges around index creation for data models:

                    How would you map a data model to Qt programming interfaces when each level within a hierarchy should correspond to a specific class?

                    Explain what you mean by that.

                    Read and abide by the Qt Code of Conduct

                    E 1 Reply Last reply 10 Oct 2018, 09:18
                    1
                    • E elfring
                      10 Oct 2018, 07:12

                      You can if you want.

                      How would you map a data model to Qt programming interfaces when each level within a hierarchy should correspond to a specific class?

                      V Offline
                      V Offline
                      VRonin
                      wrote on 10 Oct 2018, 09:03 last edited by VRonin 10 Oct 2018, 09:14
                      #14

                      In this case I'd use a generic item that supports QVariant and store the class in it as data.
                      An alternative is to have an item with a void* (or a common base class if available) containing the class instance and an int that keeps track of what type that pointer is holding so it can be dynamic_casted when needed

                      "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

                      1 Reply Last reply
                      1
                      • K kshegunov
                        10 Oct 2018, 09:01

                        @elfring said in Software development challenges around index creation for data models:

                        How would you map a data model to Qt programming interfaces when each level within a hierarchy should correspond to a specific class?

                        Explain what you mean by that.

                        E Offline
                        E Offline
                        elfring
                        wrote on 10 Oct 2018, 09:18 last edited by
                        #15

                        Explain what you mean by that.

                        Will the following hierarchy example help for a better common understanding of a possible data model?

                        1. Directories contain files.
                        2. Text files can contain several lines.
                        3. Text lines contain characters.

                        Which classes would you like to use then in your software application?

                        K 1 Reply Last reply 10 Oct 2018, 09:33
                        0
                        • V Offline
                          V Offline
                          VRonin
                          wrote on 10 Oct 2018, 09:22 last edited by
                          #16

                          I'd use the QVariant approach (so both QStandardItemModel and the one above should work) you can store directories and files as QUrls to the local path and text lines as QString

                          "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

                          E 1 Reply Last reply 10 Oct 2018, 09:34
                          0
                          • E elfring
                            10 Oct 2018, 09:18

                            Explain what you mean by that.

                            Will the following hierarchy example help for a better common understanding of a possible data model?

                            1. Directories contain files.
                            2. Text files can contain several lines.
                            3. Text lines contain characters.

                            Which classes would you like to use then in your software application?

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 10 Oct 2018, 09:33 last edited by
                            #17

                            The model infra is abstract enough so you can attach whatever you want to it. What you're describing is (kind of) a file system model with additional tweaks so you can subclass it and implement the last part. Or you can start from scratch and implement your own if you like.

                            For my current project I use the model simply as a proxy to an abstract class that holds the data (due to various reasons), so you can do that either if you like. The options are limitless ...

                            Read and abide by the Qt Code of Conduct

                            E 1 Reply Last reply 10 Oct 2018, 11:03
                            0
                            • V VRonin
                              10 Oct 2018, 09:22

                              I'd use the QVariant approach (so both QStandardItemModel and the one above should work) you can store directories and files as QUrls to the local path and text lines as QString

                              E Offline
                              E Offline
                              elfring
                              wrote on 10 Oct 2018, 09:34 last edited by
                              #18

                              I'd use the QVariant approach

                              I am occasionaly trying to avoid the data transfer by such a generic class.

                              Will it make sense to apply an other software design composition?

                              • Can it make sense to map even simple hierarchy levels to separate model classes?
                              • Should relationships between model instances be expressed separately?
                              1 Reply Last reply
                              0
                              • K kshegunov
                                10 Oct 2018, 09:33

                                The model infra is abstract enough so you can attach whatever you want to it. What you're describing is (kind of) a file system model with additional tweaks so you can subclass it and implement the last part. Or you can start from scratch and implement your own if you like.

                                For my current project I use the model simply as a proxy to an abstract class that holds the data (due to various reasons), so you can do that either if you like. The options are limitless ...

                                E Offline
                                E Offline
                                elfring
                                wrote on 10 Oct 2018, 11:03 last edited by
                                #19

                                What you're describing is (kind of) a file system model

                                Did anybody try to represent data as a file system for model variants besides the usage of the class “QFileSystemModel”?

                                with additional tweaks so you can subclass it and implement the last part.

                                I am trying again to clarify corresponding software development possibilities.

                                For my current project I use the model simply as a proxy to an abstract class that holds the data …

                                This design approach sounds very promising. How should data accesses be redirected to the existing container object here?

                                K 1 Reply Last reply 12 Oct 2018, 05:28
                                0
                                • E elfring
                                  10 Oct 2018, 11:03

                                  What you're describing is (kind of) a file system model

                                  Did anybody try to represent data as a file system for model variants besides the usage of the class “QFileSystemModel”?

                                  with additional tweaks so you can subclass it and implement the last part.

                                  I am trying again to clarify corresponding software development possibilities.

                                  For my current project I use the model simply as a proxy to an abstract class that holds the data …

                                  This design approach sounds very promising. How should data accesses be redirected to the existing container object here?

                                  K Offline
                                  K Offline
                                  kshegunov
                                  Moderators
                                  wrote on 12 Oct 2018, 05:28 last edited by kshegunov 10 Dec 2018, 05:31
                                  #20

                                  @elfring said in Software development challenges around index creation for data models:

                                  This design approach sounds very promising. How should data accesses be redirected to the existing container object here?

                                  MyModel::MyModel(QObject * parent)
                                      : QAbstractTableModel(parent), dataSource(nullptr)
                                  {
                                  }
                                  
                                  void MyModel::setDataSource(MyDataSource * source)
                                  {
                                      if (dataSource)  {
                                          QObject::disconnect(this, nullptr, dataSource, nullptr);
                                          QObject::disconnect(dataSource, nullptr, this, nullptr);
                                      }
                                  
                                      dataSource = source;
                                  
                                      QObject::connect(dataSource, &MyDataSource::dataChangeStarted, this, &MyModel::beginResetModel);
                                      QObject::connect(dataSource, &MyDataSource::dataChangeFinished, this, &MyModel::endResetModel);
                                  }
                                  
                                  QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
                                  {
                                      if (role != Qt::DisplayRole || orientation != Qt::Horizontal || section >= dataSource->columnCount())
                                          return QVariant();
                                  
                                      Q_ASSERT(dataSource);
                                      return dataSource->columnName(section);
                                  }
                                  
                                  int MyModel::rowCount(const QModelIndex &) const
                                  {
                                      Q_ASSERT(dataSource);
                                      return dataSource->rowCount();
                                  }
                                  
                                  int MyModel::columnCount(const QModelIndex &) const
                                  {
                                      Q_ASSERT(dataSource);
                                      return dataSource->columnCount();
                                  }
                                  
                                  QVariant MyModel::data(const QModelIndex & index, int role) const
                                  {
                                      Q_ASSERT(dataSource);
                                  
                                      if (!index.isValid() || role != Qt::DisplayRole)
                                          return QVariant();
                                  
                                      return dataSource->value(index.row(), index.column());
                                  }
                                  

                                  and of course the corresponding interface:

                                  
                                  class MyDataSource : public QObject
                                  {
                                      Q_OBJECT
                                      Q_DISABLE_COPY(MyDataSource)
                                  
                                  public:
                                      MyDataSource(QObject * = nullptr);
                                  
                                      virtual int rowCount() const = 0;
                                      virtual int columnCount() const = 0;
                                      virtual QString columnName(int) const = 0;
                                      virtual QVariant value(int, int) const = 0;
                                  
                                      virtual QString format(const QVariant &, int) const;
                                  
                                  signals:
                                      void changed();
                                  
                                      void dataChangeStarted();
                                      void dataChangeFinished();
                                  
                                  protected slots:
                                      virtual void reloadData() = 0;
                                  };
                                  

                                  Read and abide by the Qt Code of Conduct

                                  E V 2 Replies Last reply 12 Oct 2018, 06:32
                                  0
                                  • K kshegunov
                                    12 Oct 2018, 05:28

                                    @elfring said in Software development challenges around index creation for data models:

                                    This design approach sounds very promising. How should data accesses be redirected to the existing container object here?

                                    MyModel::MyModel(QObject * parent)
                                        : QAbstractTableModel(parent), dataSource(nullptr)
                                    {
                                    }
                                    
                                    void MyModel::setDataSource(MyDataSource * source)
                                    {
                                        if (dataSource)  {
                                            QObject::disconnect(this, nullptr, dataSource, nullptr);
                                            QObject::disconnect(dataSource, nullptr, this, nullptr);
                                        }
                                    
                                        dataSource = source;
                                    
                                        QObject::connect(dataSource, &MyDataSource::dataChangeStarted, this, &MyModel::beginResetModel);
                                        QObject::connect(dataSource, &MyDataSource::dataChangeFinished, this, &MyModel::endResetModel);
                                    }
                                    
                                    QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
                                    {
                                        if (role != Qt::DisplayRole || orientation != Qt::Horizontal || section >= dataSource->columnCount())
                                            return QVariant();
                                    
                                        Q_ASSERT(dataSource);
                                        return dataSource->columnName(section);
                                    }
                                    
                                    int MyModel::rowCount(const QModelIndex &) const
                                    {
                                        Q_ASSERT(dataSource);
                                        return dataSource->rowCount();
                                    }
                                    
                                    int MyModel::columnCount(const QModelIndex &) const
                                    {
                                        Q_ASSERT(dataSource);
                                        return dataSource->columnCount();
                                    }
                                    
                                    QVariant MyModel::data(const QModelIndex & index, int role) const
                                    {
                                        Q_ASSERT(dataSource);
                                    
                                        if (!index.isValid() || role != Qt::DisplayRole)
                                            return QVariant();
                                    
                                        return dataSource->value(index.row(), index.column());
                                    }
                                    

                                    and of course the corresponding interface:

                                    
                                    class MyDataSource : public QObject
                                    {
                                        Q_OBJECT
                                        Q_DISABLE_COPY(MyDataSource)
                                    
                                    public:
                                        MyDataSource(QObject * = nullptr);
                                    
                                        virtual int rowCount() const = 0;
                                        virtual int columnCount() const = 0;
                                        virtual QString columnName(int) const = 0;
                                        virtual QVariant value(int, int) const = 0;
                                    
                                        virtual QString format(const QVariant &, int) const;
                                    
                                    signals:
                                        void changed();
                                    
                                        void dataChangeStarted();
                                        void dataChangeFinished();
                                    
                                    protected slots:
                                        virtual void reloadData() = 0;
                                    };
                                    
                                    E Offline
                                    E Offline
                                    elfring
                                    wrote on 12 Oct 2018, 06:32 last edited by
                                    #21

                                    and of course the corresponding interface:

                                    Will your data source provide homogenous items for this model?

                                    K 1 Reply Last reply 12 Oct 2018, 06:45
                                    0
                                    • E elfring
                                      12 Oct 2018, 06:32

                                      and of course the corresponding interface:

                                      Will your data source provide homogenous items for this model?

                                      K Offline
                                      K Offline
                                      kshegunov
                                      Moderators
                                      wrote on 12 Oct 2018, 06:45 last edited by kshegunov 10 Dec 2018, 06:45
                                      #22

                                      @elfring said in Software development challenges around index creation for data models:

                                      Will your data source provide homogenous items for this model?

                                      Do you mean the data types? If so, then no, the data types are different for the different columns of the table.

                                      Read and abide by the Qt Code of Conduct

                                      E 1 Reply Last reply 12 Oct 2018, 07:11
                                      0
                                      • K kshegunov
                                        12 Oct 2018, 06:45

                                        @elfring said in Software development challenges around index creation for data models:

                                        Will your data source provide homogenous items for this model?

                                        Do you mean the data types? If so, then no, the data types are different for the different columns of the table.

                                        E Offline
                                        E Offline
                                        elfring
                                        wrote on 12 Oct 2018, 07:11 last edited by
                                        #23

                                        …, the data types are different for the different columns of the table.

                                        Will your data source work without hierarchies then?

                                        K 1 Reply Last reply 12 Oct 2018, 09:11
                                        0
                                        • K kshegunov
                                          12 Oct 2018, 05:28

                                          @elfring said in Software development challenges around index creation for data models:

                                          This design approach sounds very promising. How should data accesses be redirected to the existing container object here?

                                          MyModel::MyModel(QObject * parent)
                                              : QAbstractTableModel(parent), dataSource(nullptr)
                                          {
                                          }
                                          
                                          void MyModel::setDataSource(MyDataSource * source)
                                          {
                                              if (dataSource)  {
                                                  QObject::disconnect(this, nullptr, dataSource, nullptr);
                                                  QObject::disconnect(dataSource, nullptr, this, nullptr);
                                              }
                                          
                                              dataSource = source;
                                          
                                              QObject::connect(dataSource, &MyDataSource::dataChangeStarted, this, &MyModel::beginResetModel);
                                              QObject::connect(dataSource, &MyDataSource::dataChangeFinished, this, &MyModel::endResetModel);
                                          }
                                          
                                          QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const
                                          {
                                              if (role != Qt::DisplayRole || orientation != Qt::Horizontal || section >= dataSource->columnCount())
                                                  return QVariant();
                                          
                                              Q_ASSERT(dataSource);
                                              return dataSource->columnName(section);
                                          }
                                          
                                          int MyModel::rowCount(const QModelIndex &) const
                                          {
                                              Q_ASSERT(dataSource);
                                              return dataSource->rowCount();
                                          }
                                          
                                          int MyModel::columnCount(const QModelIndex &) const
                                          {
                                              Q_ASSERT(dataSource);
                                              return dataSource->columnCount();
                                          }
                                          
                                          QVariant MyModel::data(const QModelIndex & index, int role) const
                                          {
                                              Q_ASSERT(dataSource);
                                          
                                              if (!index.isValid() || role != Qt::DisplayRole)
                                                  return QVariant();
                                          
                                              return dataSource->value(index.row(), index.column());
                                          }
                                          

                                          and of course the corresponding interface:

                                          
                                          class MyDataSource : public QObject
                                          {
                                              Q_OBJECT
                                              Q_DISABLE_COPY(MyDataSource)
                                          
                                          public:
                                              MyDataSource(QObject * = nullptr);
                                          
                                              virtual int rowCount() const = 0;
                                              virtual int columnCount() const = 0;
                                              virtual QString columnName(int) const = 0;
                                              virtual QVariant value(int, int) const = 0;
                                          
                                              virtual QString format(const QVariant &, int) const;
                                          
                                          signals:
                                              void changed();
                                          
                                              void dataChangeStarted();
                                              void dataChangeFinished();
                                          
                                          protected slots:
                                              virtual void reloadData() = 0;
                                          };
                                          
                                          V Offline
                                          V Offline
                                          VRonin
                                          wrote on 12 Oct 2018, 08:57 last edited by
                                          #24

                                          @kshegunov said in Software development challenges around index creation for data models:

                                          QObject::connect(dataSource, &MyDataSource::dataChangeStarted, this, &MyModel::beginResetModel);
                                          QObject::connect(dataSource, &MyDataSource::dataChangeFinished, this, &MyModel::endResetModel);

                                          I know you can do better than this mate! I know you have to create and connect a gazillion signals but at least you don't build everything from scratch

                                          "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

                                          K 1 Reply Last reply 12 Oct 2018, 09:10
                                          0

                                          14/26

                                          10 Oct 2018, 09:03

                                          • Login

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