How create a calculated column on a QSqlTableModel?
-
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()); } }
-
Hi,
Why not subclass QSqlTableModel, reimplement
columnCount
and do your magic indata
? -
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; }
-
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; }
@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.
-
@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.