氏名と年齢のリストを表示するプログラムを作ろうと思う。

ui1

ボタンを押すとリストに適当なデータが追加されるものとします。

まず、氏名と年齢を持つParsonクラスを作る。ヘッダだけあげとく(ソースコード全体は最後にダウンロードできるようにしておく)

parson.h

#ifndef PARSON_H
#define PARSON_H

#include <QObject>
#include <QString>

class Parson : public QObject
{
    Q_OBJECT
public:
    explicit Parson(QObject *parent = nullptr);
    Parson(const QString &name, const int age, QObject *parent = nullptr);

signals:

public slots:

private:
    QString name;
    int age;
public:
    QString &getName();
    int getAge();
};

#endif // PARSON_H

QAbstractTableModelクラスを継承してモデル(ListModelクラス)を用意する。

ListModelクラスには、列数を返すcolumnCount、行数を返すrowCount、データを返すdata、ヘッダを返すheaderDataをオーバーライド実装する。あと、データを追加するメソッドaddを追加する。

listmodel.h

#ifndef LISTMODEL_H
#define LISTMODEL_H

#include <QAbstractTableModel>
#include <QVector>
#include "parson.h"

class ListModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit ListModel(QObject *parent = nullptr);

    virtual ~ListModel() override;

    // 列数を返す。
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    // 行数を返す。
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    // データを返す。
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    // ヘッダを返す。
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

    // データの追加
    void add(Parson *parson);
private:
    // 実際のデータの配列
    QVector<Parson*> list;
};

#endif // LISTMODEL_H

追加するメソッドをそれぞれ説明する。

まず、columnCount。列数は、氏名と年齢なので2を固定で返している。

// 列数を返す。
int ListModel::columnCount(const QModelIndex &/*parent*/) const
{
    return 2;
}

rowCount。データを保存している配列(list)の数を返している。

// 行数を返す。
int ListModel::rowCount(const QModelIndex &/*parent*/) const
{
    return list.count();
}

data。指定された列行のデータを返す。0列目が氏名で1列目が年齢とする。

// データを返す。
QVariant ListModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid() || role != Qt::DisplayRole) {
        return QVariant();
    }
    switch (index.column()) {
    case 0:
        return list[index.row()]->getName();
    case 1:
        return list[index.row()]->getAge();
    default:
        return QVariant();
    }
}

headerData。ヘッダのデータを返す。sectionが、何行目や何列目を指していて、orientationがQt::Horizontalの場合、列のヘッダを要求していることになる。

// ヘッダを返す。
QVariant ListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(role != Qt::DisplayRole) {
        return QVariant();
    }
    if(orientation == Qt::Horizontal) {
        switch (section) {
        case 0:
            return tr("Name");
        case 1:
            return tr("age");
        default:
            return QVariant();
        }
    } else {
        return QVariant(section+1);
    }
}

add。データの追加。データを挿入する場合は、beginInsertRows()を呼んで、データを追加して、終わったらendInsertRows()を呼んでやる。また、行の削除、列の追加、列の削除する場合も同様の関数を使用する必要がある。(詳細はQtのドキュメントを見てね)

// データの追加
void ListModel::add(Parson *parson)
{
    beginInsertRows(QModelIndex(), list.count(), list.count());
    list.append(parson);
    endInsertRows();
}

そして、モデルをQTableViewに設定して、Widgetのコンストラクタで初期データを追加してやる。

    model = new ListModel();
    ui->tableView->setModel(model);

    model->add(new Parson(tr("Taro Yamada"), 21));
    model->add(new Parson(tr("Hanako Yamada"), 22));

ソースの全体はここからダウンロードできる。