2013-11-07 4 views
0

Поскольку я должен сделать только небольшую модификацию модели, прозрачным прокси-сервером станет лучшая отправная точка. Этот прокси будет вставлен в цепочку моделей.Как сделать прозрачную прокси-модель: QAbstractProxyModel?

Каков самый чистый способ создания прокси-модели, чтобы все оставалось неизменным между исходной и целевой моделью в обоих направлениях?

Есть ли какие-либо тривиальные index(), mapToSource(), mapFromSource(), ... перевод используя sourceModel()?

Все, что мне нужно для расширения: data() с ролями и flags().

Я знаю, что это должно быть легко сделать, но я не хочу делать его ненужным сложным, делая это с помощью обучения.

Thanx для вашего времени.

+0

Если вам нужно расширить только 'data' и' flags', зачем вам вообще нужно QAbstractProxyModel? – vahancho

+0

@vahancho Какая альтернатива? Я не хочу менять верхнее программное обеспечение (делегат, просмотр), так как это общее решение. – urkon

+0

Не можете ли вы изменить данные и флаги исходной модели? Если нет, не можете ли вы просто наследовать существующую модель и переопределить функции data() и flags()? Я не вижу причины использовать прокси-модель, если вы не хотите ее сортировать/фильтровать. – vahancho

ответ

3

Если вы используете Qt 4.8 или более поздней версии, вы можете использовать QIdentityProxyModel, который делает именно то, что: он отображает исходную модель напрямую, без изменения структуры, так что вы можете переопределить data() и/или flags() изменить то, что вернулся.

В Qt 4.7 и более ранних версиях, самый простой способ - переопределить QSortFilterProxyModel без использования каких-либо операций сортировки или фильтрации и просто переопределить data() и flags().

+0

Qt 4.7 решение работает :) Хорошая альтернатива. – urkon

0

Я сделал свое решение. Он не изменяет индекс. На самом деле этого не должно быть. Передаются сигналы.

Цепочка модели не должна подвергаться воздействию, если эта модель вставлена ​​в нее.

#ifndef TTRANSPARENTPROXYMODEL_H 
#define TTRANSPARENTPROXYMODEL_H 

#include <QAbstractProxyModel> 

class TTransparentProxyModel : 
    public QAbstractProxyModel 
{ 
    Q_OBJECT 
public: 
    TTransparentProxyModel(QObject *parent = 0); 

    void setSourceModel(QAbstractItemModel* newSourceModel); 

    /* QAbstractProxyModel methods */ 
    virtual QModelIndex index(int, int c = 0, const QModelIndex& parent = QModelIndex()) const; 
    virtual QModelIndex parent(const QModelIndex &child) const; 
    virtual int rowCount(const QModelIndex &idx = QModelIndex()) const; 
    virtual int columnCount(const QModelIndex &parent) const; 
    virtual QModelIndex mapToSource(const QModelIndex &index) const; 
    virtual QModelIndex mapFromSource(const QModelIndex &idx) const; 
}; 

#endif // TTRANSPARENTPROXYMODEL_H 

и CPP файл:

#include "TransparentProxyModel.h" 

TTransparentProxyModel::TTransparentProxyModel(QObject *parent) 
    : QAbstractProxyModel(parent) 
{ 
} 

void TTransparentProxyModel::setSourceModel(QAbstractItemModel* newSourceModel) 
{ 
    beginResetModel(); 

    if (sourceModel()) { 
    disconnect(sourceModel(), SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), 
       this, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), 
       this, SIGNAL(rowsInserted(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), 
       this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), 
       this, SIGNAL(rowsRemoved(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
       this, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    disconnect(sourceModel(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
       this, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    disconnect(sourceModel(), SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), 
       this, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(columnsInserted(const QModelIndex &, int, int)), 
       this, SIGNAL(columnsInserted(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), 
       this, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(columnsRemoved(const QModelIndex &, int, int)), 
       this, SIGNAL(columnsRemoved(const QModelIndex &, int, int))); 
    disconnect(sourceModel(), SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
       this, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    disconnect(sourceModel(), SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
       this, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    disconnect(sourceModel(), SIGNAL(modelAboutToBeReset()), 
       this, SIGNAL(modelAboutToBeReset())); 
    disconnect(sourceModel(), SIGNAL(modelReset()), 
       this, SIGNAL(modelReset())); 
    disconnect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), 
       this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &))); 
    disconnect(sourceModel(), SIGNAL(headerDataChanged(Qt::Orientation,int,int)), 
       this, SIGNAL(headerDataChanged(Qt::Orientation,int,int))); 
    disconnect(sourceModel(), SIGNAL(layoutAboutToBeChanged()), 
       this, SIGNAL(layoutAboutToBeChanged())); 
    disconnect(sourceModel(), SIGNAL(layoutChanged()), 
       this, SIGNAL(layoutChanged())); 
    } 

    QAbstractProxyModel::setSourceModel(newSourceModel); 

    if (sourceModel()) { 
    connect(sourceModel(), SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), 
      this, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), 
      this, SIGNAL(rowsInserted(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), 
      this, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), 
      this, SIGNAL(rowsRemoved(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
      this, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    connect(sourceModel(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
      this, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    connect(sourceModel(), SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), 
      this, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(columnsInserted(const QModelIndex &, int, int)), 
      this, SIGNAL(columnsInserted(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), 
      this, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(columnsRemoved(const QModelIndex &, int, int)), 
      this, SIGNAL(columnsRemoved(const QModelIndex &, int, int))); 
    connect(sourceModel(), SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
      this, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    connect(sourceModel(), SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), 
      this, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); 
    connect(sourceModel(), SIGNAL(modelAboutToBeReset()), 
      this, SIGNAL(modelAboutToBeReset())); 
    connect(sourceModel(), SIGNAL(modelReset()), 
      this, SIGNAL(modelReset())); 
    connect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), 
      this, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &))); 
    connect(sourceModel(), SIGNAL(headerDataChanged(Qt::Orientation,int,int)), 
      this, SIGNAL(headerDataChanged(Qt::Orientation,int,int))); 
    connect(sourceModel(), SIGNAL(layoutAboutToBeChanged()), 
      this, SIGNAL(layoutAboutToBeChanged())); 
    connect(sourceModel(), SIGNAL(layoutChanged()), 
      this, SIGNAL(layoutChanged())); 
    } 
    endResetModel(); 
} 

//virtual int rowCount(const QModelIndex &idx = QModelIndex()) const; 
int TTransparentProxyModel::rowCount(const QModelIndex &parent) const 
{ 
    if(!sourceModel()) 
    { 
    return 0; 
    } 
    return this->sourceModel()->rowCount(parent); 
} 

//virtual int columnCount(const QModelIndex &idx) const; 
int TTransparentProxyModel::columnCount(const QModelIndex &parent) const 
{ 
    if(!sourceModel()) 
    { 
    return 0; 
    } 
    return this->sourceModel()->columnCount(parent); 
} 

//virtual QModelIndex index(int, int c = 0, const QModelIndex& parent = QModelIndex()) const; 
QModelIndex TTransparentProxyModel::index(int row, int column, const QModelIndex &parent) const 
{ 
    if(!this->sourceModel()) 
    { 
    return QModelIndex(); 
    } 
    return this->sourceModel()->index(row,column,parent); 
} 

//virtual QModelIndex parent(const QModelIndex &idx) const; 
QModelIndex TTransparentProxyModel::parent(const QModelIndex &child) const 
{ 
// TODO: check if this is valid. 
    QModelIndex mi = mapFromSource(child); 
    if (mi.isValid()) 
    { 
    return mi.parent(); 
    } 
    return QModelIndex(); 
} 

//virtual QModelIndex mapToSource(const QModelIndex &idx) const; 
QModelIndex TTransparentProxyModel::mapToSource(const QModelIndex &index) const 
{ 
    if(!this->sourceModel()) 
    { 
    return QModelIndex(); 
    } 
    return this->sourceModel()->index(index.row(),index.column()); 
} 


//virtual QModelIndex mapFromSource(const QModelIndex &idx) const; 
QModelIndex TTransparentProxyModel::mapFromSource(const QModelIndex &sourceIndex) const 
{ 
    if(sourceIndex.isValid()) 
    if(!this->sourceModel()) 
    { 
    return QModelIndex(); 
    } 
    return this->sourceModel()->index(sourceIndex.row(),sourceIndex.column()); 
} 

Я попытался поймать все сигналы от источника и сигнала таким же образом к следующей модели.

Единственный метод, я не уверен, правильно ли он выполнен, это parent().

Надеюсь, это полезно.

Смежные вопросы