Qt Forum

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

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Solved How create a calculated column on a QSqlTableModel?

    General and Desktop
    3
    7
    1166
    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.
    • L
      lqsa last edited by lqsa

      I would like to show a calculated column on a QTableView where the source is a QSqlTableModel. I've tried a custom QIdentityProxyModel, but the data method for the added column is never called.

      For example, if the database has 3 fields, and added a column with the addColumn method, the data method is never called with an index with column 3, only 0, 1 and 2 (the 3 database fields). However, columnCount returns 4 (3 database fields + 1 of the added column).

      class CalculatedColumn
      {
      public:
          CalculatedColumn();
          virtual QVariant calculate(int row) const = 0;
      };
      
      
      class SqlQueryModelCalculatedColumns: public QIdentityProxyModel
      {
      public:
          SqlQueryModelCalculatedColumns(QObject *parent = 0);
          void addColumn(CalculatedColumn *column);
          int columnCount(const QModelIndex &parent) const override;
          QVariant data(const QModelIndex &index, int role) const override;    
      private:
          QVector<CalculatedColumn *> m_columns;
      }
      
      
      SqlQueryModelCalculatedColumns::SqlQueryModelCalculatedColumns(QObject *parent): QIdentityProxyModel(parent)
      {
      }
      
      void SqlQueryModelCalculatedColumns::addColumn(CalculatedColumn *column)
      {
          const int count = sourceModel()->columnCount();
          beginInsertColumns(QModelIndex(), count, count);
          m_columns.append(column);
          endInsertColumns();
      }
      
      int SqlQueryModelCalculatedColumns::columnCount(const QModelIndex &parent) const
      {
          return sourceModel()->columnCount(parent) + m_columns.count();
      }
      
      QVariant SqlQueryModelCalculatedColumns::data(const QModelIndex &index, int role) const
      {
          const int column = index.column();
          const int count = sourceModel()->columnCount();
          if (column < count) {
              return sourceModel()->data(index, role);
          }
          else {
              const int iCalculatedColumn = column - count;
              CalculatedColumn *calculatedColumn = m_columns.at(iCalculatedColumn);
              return calculatedColumn->calculate(index.row());
          }
      }
      
      
      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi,

        Why not subclass QSqlTableModel, reimplement columnCount and do your magic in data ?

        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 Reply Quote 1
        • L
          lqsa last edited by

          I did it. It was the first attempt, but occurs the same.

          JonB 1 Reply Last reply Reply Quote 0
          • JonB
            JonB @lqsa last edited by

            @lqsa
            If you're saying you did originally take @SGaist 's approach, but it "didn't work", we'll need to see that code....

            1 Reply Last reply Reply Quote 0
            • L
              lqsa last edited by

              Only appears the dataset columns:

              class SqlTableModel : public QSqlTableModel {
              public:
                  explicit SqlTableModel(QObject *parent = 0);    
                  QVariant data(const QModelIndex &index, int role) const override;
                  int columnCount(const QModelIndex &parent) const override;
              };
              
              
              
              SqlTableModel::SqlTableModel(QObject *parent): QSqlTableModel(parent)
              {
              }
              
              QVariant SqlTableModel::data(const QModelIndex &index, int role) const
              {
                  if ((role == Qt::DisplayRole) && (index.column() == columnCount(QModelIndex()))) {
                      return "Hello";
                  }
                  else {
                      return QSqlTableModel::data(index, role);
                  }
              }
              
              int SqlTableModel::columnCount(const QModelIndex &parent) const
              {
                  const int count = QSqlTableModel::columnCount(parent) +1;
                  return count;
              }
              

              0_1530094290605_Table.png

              JonB 1 Reply Last reply Reply Quote 0
              • JonB
                JonB @lqsa last edited by JonB

                @lqsa said in How create a calculated column on a QSqlTableModel?:

                index.column() == columnCount(QModelIndex())

                How is this right? Index column will never be equal to columnCount()? Don't you mean
                index.column() == columnCount(QModelIndex()) - 1
                ?

                I don't know whether that will solve your problem, but it's a start.

                L 1 Reply Last reply Reply Quote 2
                • L
                  lqsa @JonB last edited by

                  @JonB Yes, must be -1. Now this simple sample works. Thank you very much.

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