ymoreau ymoreau - 2 months ago 41
C++ Question

Add virtual column to Qt SQL model using a proxy

I display an SQL table in a view using a QSqlTableModel.

I want to display an additional status column based on the row data, for that I use a custom QIdentityProxyModel where I increase the columnCount and return data for that new virtual column which does not exist in the QSqlTableModel.

int MyProxyModel::columnCount(const QModelIndex& parent) const
{
return sourceModel() ? (sourceModel()->columnCount() + 1) : 0;
}

QVariant MyProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (section == columnCount()-1 &&
orientation == Qt::Horizontal &&
role == Qt::DisplayRole)
{
return tr("MyHeader");
}

return QIdentityProxyModel::headerData(section, orientation, role);
}

QVariant MyProxyModel::data(const QModelIndex &proxyIndex, int role) const
{
qDebug() << "data " << proxyIndex.row() << proxyIndex.column();
// ...never called for my extra column (== columnCount()-1)

if (proxyIndex.column() == columnCount()-1 && role == Qt::DisplayRole)
return QString("I am virtual");

return QIdentityProxyModel::data(proxyIndex, role);
}


Edit: I changed the code for something more simple regarding to the comments. I still have the same problem.

My problem is that the view never asks data for my virtual column, it calls data() for all other columns of the actual SQL table but not the last virtual one, what have I missed ?
Also, the header data is working well for my extra column, the problem is only with the data. The view draws the extra column, but content is empty (even alternating row background is not painted).
Thx !

Answer

The view needs to get the QModelIndex objects for the virtual column, so I also needed to override the index function in the proxy :

QModelIndex MyProxyModel::index(int row, int column, const QModelIndex &parent) const
{
    if (column == columnCount()-1)
        return createIndex(row, column);

    return QIdentityProxyModel::index(row, column);
}

I didn't mind the parent because I only have a table (from database), though I do not know how it could be dealt with if needed because createIndex does not allow to specify a parent.