2012-08-10 13 views
13

Im Qtプログラミングでは非常に新しいです。私はXMLファイルから取得したQt TableViewでデータを表示したいと思います。Qt TableViewへのモデルのバインド

カスタムモデルを作成してTableViewにバインドする方法に関する有用なチュートリアルが見つかりません。

いくつかのヘルプを提供するか、誰かが良い例があれば教えてください。

おかげ

答えて

24

Qtのモデルビューアプローチは非常に汎用性があります。すべてのモデルはQAbstractItemModelから継承しています。このクラスを使用すると、非常に複雑なデータレイアウト(リスト、ツリー、テーブルなど)を作成できますが、インプリメンテーションの労力はかなり高いです。

すぐに使用できるクラスは、QStandardItemModelです。テーブルモデルを簡単に作成し、項目を追加すると、QStandardItemというインスタンスになります。次のコードを使用して開始することができます。

#include <QtGui> 

QStandardItemModel* createModel(QObject* parent) 
{ 
    const int numRows = 10; 
    const int numColumns = 10; 

    QStandardItemModel* model = new QStandardItemModel(numRows, numColumns); 
    for (int row = 0; row < numRows; ++row) 
    { 
     for (int column = 0; column < numColumns; ++column) 
     { 
      QString text = QString('A' + row) + QString::number(column + 1); 
      QStandardItem* item = new QStandardItem(text); 
      model->setItem(row, column, item); 
     } 
    } 

    return model; 
} 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    QMainWindow window; 
    QTableView* view = new QTableView; 
    view->setModel(createModel(view)); 
    window.setCentralWidget(view); 
    window.show(); 

    return app.exec(); 
} 

これは本当に使いやすいです。しかし、欠点は、QStandardItemでデータを供給しなければならないことです。これはメモリの無駄です。たとえば、ビューに表示するデータが100MBあるとします。既にデータをどこかに保存しているので、すべてのセルに対してQStandardItemを作成するのではなく、ビューで使用できるように変更することをお勧めします。

これはQAbstractTableModelが出場するところです。次の例では、250.000エントリの行列 を作成します。代わりに、我々サブクラスQAbstractTableModel 、すべての行列要素のための1つQStandardItemを作成し、行、列、および表示する データの数を返す3つの純粋仮想メソッド numRows()numColumns()data()を実装します。

#include <QtGui> 

class MatrixModel : public QAbstractTableModel 
{ 
public: 
    MatrixModel(int numRows, int numColumns, double* data) 
     : m_numRows(numRows), 
      m_numColumns(numColumns), 
      m_data(data) 
    { 
    } 

    int rowCount(const QModelIndex& parent = QModelIndex()) const 
    { 
     return m_numRows; 
    } 

    int columnCount(const QModelIndex& parent = QModelIndex()) const 
    { 
     return m_numColumns; 
    } 

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const 
    { 
     if (!index.isValid() || role != Qt::DisplayRole) 
      return QVariant(); 

     // Return the data to which index points. 
     return m_data[index.row() * m_numColumns + index.column()]; 
    } 

private: 
    int m_numRows; 
    int m_numColumns; 
    double* m_data; 
}; 


int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    // Create a matrix. 
    const int numRows = 500; 
    const int numColumns = 500; 
    double matrix[numRows][numColumns]; 
    for (int i = 0; i < numRows; ++i) 
     for (int j = 0; j < numColumns; ++j) 
      matrix[i][j] = i + j; 

    // Create a model which adapts the data (the matrix) to the view. 
    MatrixModel model(numRows, numColumns, (double*)matrix); 

    QMainWindow window; 
    QTableView* view = new QTableView; 
    view->setModel(&model); 
    window.setCentralWidget(view); 
    window.show(); 

    return app.exec(); 
} 

ご覧のとおり、モデルはデータを複製するのではなく、アダプタとして機能します。さらに柔軟性が必要な場合は、QAbstractItemModelに移動し、 のモデルインデックスを作成するイベント実装 を使用してください。

1

あなたは常に変化XMLソースから積極的に読むことができるよう、更新したいので、あなたがカスタムモデルをしたいですか?

そうでない場合は、通常のQTableViewチュートリアルとQStandardItemModelを使用できます。 XMLファイルを自分で解析し、QStandardItemオブジェクトを作成してモデルに追加します。

カスタムモデルは、XMLファイルの読み込みをモデル自体に直接統合する方法です。これは、外部にアイテムを格納するアイテムベースのアプローチとは異なります。

関連する問題