今回はカスタムModelをQTableViewに表示します。
C++ GUI Programming with Qt4のサンプルをそのまま使うと動かないので一部変えて使用します。それではコードを
(C++ GUI Programming with Qt4 231ページを一部改変)
(currencymodel.h)
#include <QAbstractTableModel> class CurrencyModel : public QAbstractTableModel { Q_OBJECT//マクロ "Qtをはじめよう"か何かで確認してください。 public: explicit CurrencyModel(QObject *parent = 0);//コンストラクタ void setCurrencyMap(const QMap<QString, double> &map); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; private: QString currencyAt(int offset) const; QMap<QString, double> currencyMap; };
(currencymodel.cpp)
#include "currencymodel.h" CurrencyModel::CurrencyModel(QObject *parent) : QAbstractTableModel(parent)//ただparentを基本クラスに渡すだけ { } int CurrencyModel::rowCount(const QModelIndex & /* parent */) const { return currencyMap.count();//使わないのでparentはコメントアウトしている↑ } int CurrencyModel::columnCount(const QModelIndex & /* parent */) const { return currencyMap.count();//使わないのでparentはコメントアウトしている↑ } QVariant CurrencyModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::TextAlignmentRole) { return int(Qt::AlignRight | Qt::AlignVCenter); } else if (role == Qt::DisplayRole) { QString rowCurrency = currencyAt(index.row()); QString columnCurrency = currencyAt(index.column()); if (currencyMap.value(rowCurrency) == 0.0) return "####"; double amount = currencyMap.value(columnCurrency) / currencyMap.value(rowCurrency); return QString("%1").arg(amount, 0, 'f', 4); } return QVariant(); }//ようはデータを返すもの QVariant CurrencyModel::headerData(int section, Qt::Orientation /* orientation */, int role) const { if (role != Qt::DisplayRole) return QVariant(); return currencyAt(section); }//ビューの行ヘッダとカラムヘッダを表示するために使う void CurrencyModel::setCurrencyMap(const QMap<QString, double> &map) { currencyMap = map; reset(); }//QMapをフィールドのcurrencyMapにセット QString CurrencyModel::currencyAt(int offset) const { return (currencyMap.begin() + offset).key(); }//ようは通貨コードを返す
はい長いですね。ヘッダ部で重要なのはQAbstructTableModelを継承しているということです。cppのほうもあまり難しいことは行っていません。コメントの説明だけでわかるでしょう。
次にこれを使ってQTableViewに表示します。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)//uiにはGUI関連の記述がなされています。 { ui->setupUi(this);//GUI部品の初期化。QTableViewもここで初期化される。 QMap<QString, double> currencyMap; currencyMap.insert("AUD", 1.3259); currencyMap.insert("CHF", 1.2970); currencyMap.insert("SGD", 1.6901); currencyMap.insert("USD", 1.0000); currencyMap.insert("JPN", 1.0000); CurrencyModel *cModel = new CurrencyModel();/*注意!newしてください。本の通りだと表示できません*/ cModel->setCurrencyMap(currencyMap);//作ったQMapをセット ui->tableView->setModel(cModel);//カスタムモデルをテーブルビューにセット }
前回同様、uiにQTableViewや他のGUI部品の定義が既にしてあるものと考えてください。QMapでデータの元を作成し、それを先に作ったCurrencyModelにセットして、テーブルビューにセットして表示しています。
実行結果は以下のようになります。
かなり端折って書きました。後で加筆するかもしれません。
とりあえず以上です。
※加筆: モデルクラスの継承関係