Qt QSortfilterproxy模型虚拟列

时间:2018-02-23 21:55:17

标签: qt qtsql qsqltablemodel qsortfilterproxymodel

ymoreau here已提出相关问题 - 但没有决定性的解决方案。我已经将QSortFilterProxyModel子类化,目的是在QSqlRelationalTableModel(sourceModel)的数据来自MYSQL数据库的虚拟列中显示一些数据。

以下是我的代码:

class vModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit vModel(QObject *parent): QSortFilterProxyModel(parent)
{
}
virtual QModelIndex index(int row, int column) const
 {
     if(column >= columnCount()-1){
         return createIndex(row,column);
     }
     else
         return QSortFilterProxyModel::index(row, column);
 }
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const
{
    Q_UNUSED(parent);
    return sourceModel() ? (sourceModel()->columnCount() + 1) : 0;
}
virtual bool setData(const QModelIndex &index, const QVariant &value, int    role = Qt::EditRole)
{
    if (index.isValid() && role == Qt::EditRole)
    {
        QSortFilterProxyModel::setData(index,value,role);
        emit dataChanged(index,index);
        return true;
    }
    else
        return false;
}
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const
{
    int amtCol = columnCount()-1;
    if (orientation == Qt::Horizontal
            && section == amtCol
            && role == Qt::DisplayRole){
        return QString("Amount");
    }
    else
        return QSortFilterProxyModel::headerData(section, orientation, role);
}

virtual QModelIndex parent(const QModelIndex &index) const {
    Q_UNUSED(index);
    return QModelIndex();
}
virtual QVariant data(const QModelIndex &index, int role) const
{
    int amtCol = columnCount()-1;

    if(index.column() == amtCol ){
        if (role != Qt::DisplayRole)
            return QSortFilterProxyModel::data(index, role);
        else{
            QString val = QString("Amount Index(%1,%2)").arg(index.row()).arg(index.column());
            return val;
        }
    }
    return QSortFilterProxyModel::data(index, role);
}
virtual QModelIndex mapFromSource(const QModelIndex &source) const
{
    return index(source.row(), source.column());
}

virtual QModelIndex mapToSource(const QModelIndex &proxy) const
{
    return (sourceModel()&&proxy.isValid())
        ? sourceModel()->index(proxy.row(), proxy.column(), proxy.parent())
        : QModelIndex();
}
protected:
Qt::ItemFlags flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QSortFilterProxyModel::flags(index);
    if (index.isValid())
    {
        flags |= Qt::ItemIsSelectable |  Qt::ItemIsEditable | Qt::ItemIsEnabled;
    }
    return flags;
}
};

视图使用我指定的正确标题绘制额外列,但即使交替行背景未绘制,内容也为空。当我查询额外的列索引时,模型返回正确的数据。当我检查虚拟列中任何索引的有效性但是我的子类模型返回true时,委托返回false。

我的问题在哪里......是模特还是代表?是否还需要包含其他功能?

1 个答案:

答案 0 :(得分:-1)

对Sourcemodel进行子类化很容易产生我的期望。我相信QIdentityProxyModel或任何其他代理可以执行相同的任务,但你必须处理这么多问题。 My Sourcemodel(QSqlRelationalTableModel)响应数据更改(超过4个虚拟列中的计算值)并轻松地与默认关系委托进行通信。

如果要让代理模型完成此任务,我仍然欢迎这些建议。我使用的是Qt5.9