2009-09-07 22 views
5

申し訳ありませんが、実際には基本的にQStandardItemModelという数字が入力されています。私はそれをQTableViewに表示することができました。私は新しいモデル(サブクラスのいずれかQAbstractItemModelまたはQAbstractProxyModel)を作成しました。これは既存のモデルのレイヤーの一部です。ソースモデルを設定する必要があり、この新しいレイヤーは実際のモデルでいくつかの変換を行う必要があります。QTでは、チェーンモデルが正常に動作しません

私の問題は、トップレイヤーでは、レイヤーモデルdata(const QModelIndex & index, int role)メンバー関数が呼び出されなかったと言いますが、ロールパラメータで表示方法を変更したいと思います。

ここでは、元のモデルのdata(index,role)が常に呼び出され、レイヤーモデルのdata(index,role)は絶対に呼び出されないことを示すサンプルコードを示します。どうして? QTableViewオブジェクトは、どのようにして最上位層の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

[OK]を、私は参照してください。私は次に2つの質問を持っています: - プロキシインデックスを作成せずに目標を達成するにはどうしたらいいですか?私はプロキシモデルでインデックスを作成しないようにしたいと思います。なぜなら、フィルタリング/並べ替えなどが行われず、元のモデルのインデックスを完全に複製するからです。 - 'QSortFilterProxyModel'がどのように私を助けてくれるのか分かりません。私は 'data(..)'関数をコーディングしなければなりません。上記のために、 'index(...)'もコード化する必要があります。 'QSortFilterProxyModel'は' QAbstractProxyModel'が私の視点ではないことをしていますか? –

+1

プロキシモデルを指す新しいインデックスを作成する必要があります。 QSortFilterProxyModeはあなたのためにプロキシインデックスを作成します。 – TimW

+0

ありがとう、mapToSourceとmapFromSourceは私にとって悪魔の目でした!それは魅力のように機能します! –

関連する問題