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. How create a calculated column on a QSqlTableModel?
QtWS25 Last Chance

How create a calculated column on a QSqlTableModel?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 1.6k 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.
  • L Offline
    L Offline
    lqsa
    wrote on last edited by lqsa
    #1

    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
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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
      1
      • L Offline
        L Offline
        lqsa
        wrote on last edited by
        #3

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

        JonBJ 1 Reply Last reply
        0
        • L lqsa

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

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @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
          0
          • L Offline
            L Offline
            lqsa
            wrote on last edited by
            #5

            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

            JonBJ 1 Reply Last reply
            0
            • L lqsa

              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

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @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
              2
              • JonBJ 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 Offline
                L Offline
                lqsa
                wrote on last edited by
                #7

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

                1 Reply Last reply
                0

                • Login

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