使用代理向Qt SQL模型添加虚拟列

Add virtual column to Qt SQL model using a proxy

本文关键字:模型 添加 虚拟 SQL Qt 代理      更新时间:2023-10-16

我使用QSqlTableModel在视图中显示一个SQL表。

我想根据行数据显示一个额外的状态列,为此我使用自定义QIdentityProxyModel,其中我增加columnCount并返回数据为新的虚拟列,不存在于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);
}

编辑:我改变了一些更简单的关于注释的代码。我还是有同样的问题

我的问题是,视图从来没有问我的虚拟列的数据,它调用data()为实际SQL表的所有其他列,但不是最后一个虚拟的,我错过了什么?此外,标题数据对于我的额外列来说工作得很好,问题只在于数据。视图绘制额外的列,但内容为空(即使交替行背景也不会绘制)。谢谢!

视图需要获取虚拟列的QModelIndex对象,因此我还需要在代理中覆盖index函数:

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

我不介意父,因为我只有一个表(从数据库),虽然我不知道它可以如何处理,如果需要,因为createIndex不允许指定父

不需要m_mySqlTableColumnCount成员。您必须通过侦听更新列数的源模型信号来确保它始终是正确的。唉,这是不必要的。您希望将列计数请求传递到源模型:

int MyProxyModel::columnCount(const QModelIndex& parent) const
{
    return sourceModel() ? (QIdentityProxyModel::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
{
    if (proxyIndex.column() == columnCount()-1) {
      qDebug() << proxyIndex.row() << proxyIndex.column();
      ...
    }
    return QIdentityProxyModel::data(proxyIndex, role);
}