2009-09-07 3 views
5

좋아요, 저는 숫자가 많은 QStandardItemModel을 가지고 있습니다. 나는 QTableView에 그것을 표시 할 수 있었다, 괜찮아. 새로운 모델 (서브 클래스는 QAbstractItemModel 또는 QAbstractProxyModel)을 만들었습니다. 기존 모델의 일부 레이어입니다. 소스 모델을 설정하는 데 필요하며이 새로운 레이어는 실제 모델에서 일부 변형을 수행해야합니다.QT에서 체인 모델이 예상대로 작동하지 않습니다.

내 문제는 최상위 레이어에서 "레이어 모델"이라고 말하면 data(const QModelIndex & index, int role) 멤버 함수는 호출되지 않았지만 역할 매개 변수로 표시 방법을 변경하고 싶습니다.

다음은 원래 모델 data(index,role)이 항상 호출되는 반면 레이어 모델 data(index,role)은 절대 호출되지 않는다는 것을 보여주는 샘플 코드입니다. 왜? QTableView 객체가 어떻게 최상위 레이어의 "skip"을 할 수 있습니까? data(index,role)?

#include <QtGui/QApplication> 
#include <QtGui> 
#include <QStandardItemModel> 

class MyModel : public QStandardItemModel 
{ 
public: 
    MyModel(const int r, const int c, QObject* parent = 0) : QStandardItemModel(r,c,parent) {} 
    QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const { 
     qDebug() << "mymodel data"; 
     return this->itemFromIndex(index)->data(role); 
    } 
}; 

class MyProxyModel : public QAbstractProxyModel 
{ 
public: 

    MyProxyModel(QObject* parent = 0) : QAbstractProxyModel(parent) {} 
    QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const { 
     return this->sourceModel()->index(row,column,parent); 
    } 
    QModelIndex parent (const QModelIndex & index) const { 
     return this->sourceModel()->parent(index); 
    } 
    QModelIndex mapFromSource (const QModelIndex & sourceIndex) const 
    { 
     return sourceIndex; 
    } 
    QModelIndex mapToSource (const QModelIndex & proxyIndex) const 
    { 
     return proxyIndex; 
    } 
    QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const { 
     qDebug() << "myproxymodel data"; 
     return this->sourceModel()->data(index,role); 
    } 

    int rowCount (const QModelIndex & parent = QModelIndex()) const { 
     return this->sourceModel()->rowCount(parent); 
    } 
    int columnCount (const QModelIndex & parent = QModelIndex()) const { 
     return this->sourceModel()->columnCount(parent); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc,argv); 
    MyModel model(8, 2); 
    MyProxyModel mymodel; 
    mymodel.setSourceModel(&model); 

    QTableView tableView; 
    tableView.setModel(&mymodel); 

    tableView.horizontalHeader()->setStretchLastSection(true); 
    for (int row = 0; row < 8; ++row) { 
     for (int column = 0; column < 2; ++column) { 
      QModelIndex index = model.index(row, column, QModelIndex()); 
      model.setData(index, QVariant((row+1) * (column+1))); 
     } 

    } 
    tableView.show(); 
    return app.exec(); 
} 

답변

6

QTableView는 모델 색인을 사용하여 데이터를 검색하기 때문에 아마도 이와 유사합니다.

QModelIndex index = model->index(row, column, parentIndex); 
index.data(Qt::DisplayRole); 

그리고 당신은 프록시 모델에 인덱스 대신 소스 모델의 모델 인덱스를 반환됩니다

QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const { 
    return this->sourceModel()->index(row,column,parent); 
} 

시도를 프록시 모델 인덱스에 모델 인덱스를 변환하는

QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const { 
    return this->createIndex(row,column,row); 
} 

지도를 원본으로 다시 작성하고 원본 기능에서 매핑하는 것을 잊지 마십시오.


솔루션

class MyTableProxyModel : public QAbstractProxyModel 
{ 
    Q_OBJECT 
public: 
    MyTableProxyModel (QObject* parent = 0) 
     : QAbstractProxyModel(parent) { 
    } 

    QModelIndex index(int row, int column, const QModelIndex& parent=QModelIndex()) const { 
     return createIndex(row,column,row); 
    } 

    QModelIndex parent(const QModelIndex &index) const { 
     //Works only for non-tree models 
     return QModelIndex(); 
    } 

    QModelIndex mapFromSource(const QModelIndex &source) const { 
     return index(source.row(), source.column(), source.parent()); 
    } 

    QModelIndex mapToSource(const QModelIndex &proxy) const { 
     return (sourceModel()&&proxy.isValid()) 
      ? sourceModel()->index(proxy.row(), proxy.column(), proxy.parent()) 
      : QModelIndex(); 
    } 

    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { 
     qDebug() << "myproxymodel data"; 
     return mapToSource(index).data(role); 
    } 

    int rowCount (const QModelIndex & parent = QModelIndex()) const { 
     return sourceModel() ? sourceModel()->rowCount(parent) : 0; 
    } 

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

좋아, 난을 참조하십시오. 다음 질문이 두 개 있습니다. - 프록시 색인을 만들지 않고 목표를 달성하려면 어떻게해야합니까? 프록시 모델에서 인덱스 생성을 피하고 싶습니다. 필터링/정렬 등이 없기 때문에 원본 모델의 인덱스를 완벽하게 복제 할 수 있기 때문입니다. -'QSortFilterProxyModel'이 어떻게 도움이되는지 모르겠습니다. 나는'data (..)'함수를 코딩해야하고, 위의 이유로, 나는 또한'index (...)'코드를 필요로한다. 'QSortFilterProxyModel'은'QAbstractProxyModel'을 내 관점에서 보지 않습니다. –

+1

프록시 모델을 가리키는 새 인덱스를 만들어야합니다. QSortFilterProxyMode는 프록시 색인을 작성합니다. – TimW

+0

대단히 고맙습니다. mapToSource와 mapFromSource가 나를위한 악마의 눈이었습니다! 그것은 매력처럼 작동합니다! –

관련 문제