このページの内容

Qt Quick のビューとC++モデルの連携

カスタム C++ モデルで提供されるデータ

モデルは C++ で定義し、QML から利用できるようにすることができます。これは、既存の C++ データモデルや、それ以外の複雑なデータセットを QML に公開する場合に役立ちます。

C++モデルクラスは、QStringList 、QVariantList 、QObjectList 、またはQAbstractItemModel として定義できます。最初の3つは、より単純なデータセットを公開するのに役立ちますが、QAbstractItemModel は、より複雑なモデルに対してより柔軟なソリューションを提供します。

QStringList ベースのモデル

モデルは、modelDataロールを通じてリストの内容を提供する単純なQStringList である場合があります。

以下は、modelData ロールを使用してモデル項目の値を参照するデリゲートを持つListView の例です。

ListView {
    width: 100
    height: 100
    required model

    delegate: Rectangle {
        required property string modelData
        height: 25
        width: 100
        Text { text: parent.modelData }
    }
}

Qtアプリケーションは、このQMLドキュメントを読み込み、myModel の値をQStringList に設定できます:

    QStringList dataList = {
        "Item 1",
        "Item 2",
        "Item 3",
        "Item 4"
    };

    QQuickView view;
    view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});

この例の完全なソースコードは、Qtのインストールディレクトリ内のexamples/quick/models/stringlistmodelにあります。

注: ビュー側では、QStringList の内容が変更されたことを知る方法はありません 。QStringList が変更された場合は、ビューのmodel プロパティを再度設定して、モデルをリセットする必要があります。

QVariantList ベースのモデル

モデルは単一のQVariantList である場合があり、この場合、modelDataロールを通じてリストの内容を提供します。

API の動作は、前のセクションで示したQStringList の場合とまったく同じです。

注: ビューがQVariantList の内容が変更されたことを知る方法はありません 。QVariantList が変更された場合は、ビューのmodel プロパティを再度設定して、モデルをリセットする必要があります。

QObjectList ベースのモデル

QObject* の値のリストもモデルとして使用できます。QList<QObject*> は、リスト内のオブジェクトのプロパティをロールとして提供します。

以下のアプリケーションは、Q_PROPERTY の値を持つDataObject クラスを作成します。これにより、QList<DataObject*>がQMLに公開された際、それらの値は名前付きロールとしてアクセス可能になります:

class DataObject : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
    ...
};

int main(int argc, char ** argv)
{
    QGuiApplication app(argc, argv);

    const QStringList colorList = {"red",
                                   "green",
                                   "blue",
                                   "yellow"};

    const QStringList moduleList = {"Core", "GUI", "Multimedia", "Multimedia Widgets", "Network",
                                    "QML", "Quick", "Quick Controls", "Quick Dialogs",
                                    "Quick Layouts", "Quick Test", "SQL", "Widgets", "3D",
                                    "Android Extras", "Bluetooth", "Concurrent", "D-Bus",
                                    "Gamepad", "Graphical Effects", "Help", "Image Formats",
                                    "Location", "Mac Extras", "NFC", "OpenGL", "Platform Headers",
                                    "Positioning", "Print Support", "Purchasing", "Quick Extras",
                                    "Quick Timeline", "Quick Widgets", "Remote Objects", "Script",
                                    "SCXML", "Script Tools", "Sensors", "Serial Bus",
                                    "Serial Port", "Speech", "SVG", "UI Tools", "WebEngine",
                                    "WebSockets", "WebView", "Windows Extras", "XML",
                                    "XML Patterns", "Charts", "Network Authorization",
                                    "Virtual Keyboard", "Quick 3D", "Quick WebGL"};

    QList<QObject *> dataList;
    for (const QString &module : moduleList)
        dataList.append(new DataObject("Qt " + module, colorList.at(rand() % colorList.length())));

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});
    ...

QObject* は、modelData プロパティとして利用可能です。利便性のため、オブジェクトのプロパティはデリゲートのコンテキスト内でも直接利用できるようになっています。ここでは、view.qml がListView デリゲート内のDataModel プロパティを参照しています:

ListView {
    id: listview
    width: 200; height: 320
    required model
    ScrollBar.vertical: ScrollBar { }

    delegate: Rectangle {
        width: listview.width; height: 25

        required color
        required property string name

        Text { text: parent.name }
    }
}

color プロパティの使用に注意してください。派生型でrequired として宣言することで、既存のプロパティを必須とすることができます。

この例の完全なソースコードは、Qtのインストールディレクトリ内のexamples/quick/models/objectlistmodelにあります。

注: ビュー側では、QObjectList の内容が変更されたことを知る方法はありません 。QObjectList が変更された場合は、ビューのmodel プロパティを再度設定して、モデルをリセットする必要があります。

QAbstractItemModel のサブクラス

モデルは、QAbstractItemModel をサブクラス化することで定義できます。これは、他の方法ではサポートできないような、より複雑なモデルがある場合に最適なアプローチです。また、QAbstractItemModel は、モデルデータが変更された際にQMLビューに自動的に通知することもできます。

QAbstractItemModel のサブクラスのロールは、QAbstractItemModel::roleNames()を再実装することでQMLに公開できます。

以下は、`AnimalModel` という名前の `QAbstractListModel ` のサブクラスを持つアプリケーションの例です。このサブクラスは、`type` および`sizes` ロールを公開しています。また、`QAbstractItemModel::roleNames()` を再実装してロール名を公開しており、これにより QML からアクセスできるようになっています。

class Animal
{
public:
    Animal(const QString &type, const QString &size);
    ...
};

class AnimalModel : public QAbstractListModel
{
    Q_OBJECT
public:
    enum AnimalRoles {
        TypeRole = Qt::UserRole + 1,
        SizeRole
    };

    AnimalModel(QObject *parent = nullptr);
    ...
};

QHash<int, QByteArray> AnimalModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[TypeRole] = "type";
    roles[SizeRole] = "size";
    return roles;
}

int main(int argc, char ** argv)
{
    QGuiApplication app(argc, argv);

    AnimalModel model;
    model.addAnimal(Animal("Wolf", "Medium"));
    model.addAnimal(Animal("Polar bear", "Large"));
    model.addAnimal(Animal("Quoll", "Small"));

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.setInitialProperties({{"model", QVariant::fromValue(&model)}});
    ...

このモデルは、`type`および`size`ロールにアクセスするListView デリゲートによって表示されます:

ListView {
    width: 200; height: 250

    required model

    delegate: Text {
        required property string type
        required property string size

        text: "Animal: " + type + ", " + size
    }
}

モデルが変更されると、QMLビューは自動的に更新されます。モデルはモデル変更に関する標準的なルールに従う必要があり、変更があった場合はQAbstractItemModel::dataChanged()やQAbstractItemModel::beginInsertRows()などを使用してビューに通知しなければならない点に注意してください。詳細については、「モデルのサブクラス化リファレンス」を参照してください。

この例の完全なソースコードは、Qt インストールディレクトリ内のexamples/quick/models/abstractitemmodelにあります。

QAbstractItemModel はテーブルの階層構造を表していますが、QMLが現在提供しているビューではリストデータしか表示できません。階層型モデルの子リストを表示するには、DelegateModel というQML型を使用します。この型は、QAbstractItemModel 型のリストモデルで使用するための以下のプロパティと関数を提供しています:

C++ データモデルを QML に公開する

上記の例では、QMLコンポーネント内でモデル値を直接設定するために、ビューの必須プロパティを使用しています。これに代わる方法として、C++モデルクラスをQML型として登録することもできます(「C++からのQML型の定義」を参照)。これにより、モデルクラスをQML内の型として直接作成できるようになります:

C++
class MyModel : public QAbstractItemModel
{
    Q_OBJECT
    QML_ELEMENT

    // [...]
}
QML
MyModel {
    id: myModel
}
ListView {
    width: 200; height: 250
    model: myModel
    delegate: Text {
        required property string someProperty
        text: someProperty
    }
}

C++での QML 型の記述に関する詳細については、「C++ を使用した QML 拡張機能の作成」を参照してください。

モデルデータの変更

roleNames() およびdata() に加え、編集可能なモデルは、既存のモデルデータへの変更を保存するためにsetData メソッドを再実装する必要があります。以下のメソッドのバージョンは、指定されたモデルインデックスが有効であるか、およびrole がQt::EditRole と等しいかを確認します:

bool EditableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (index.isValid() && role == Qt::EditRole) {
        // Set data in model here. It can also be a good idea to check whether
        // the new value actually differs from the current value
        if (m_entries[index.row()] != value.toString()) {
            m_entries[index.row()] = value.toString();
            emit dataChanged(index, index, { Qt::EditRole, Qt::DisplayRole });
            return true;
        }
    }
    return false;
}

注: 変更を保存した後は、dataChanged() シグナルを発生させることが重要です 。

QListView やQTableView といったC++のアイテムビューとは異なり、setData() メソッドは、必要に応じてQMLデリゲートから明示的に呼び出す必要があります。これは、対応するモデルプロパティに新しい値を割り当てるだけで実行されます。

ListView {
    anchors.fill: parent
    model: EditableModel {}
    delegate: TextField {
        width: ListView.view.width
        text: model.edit
        onAccepted: model.edit = text
    }
}

注: edit ロールは Qt::EditRole と同等です。組み込みのロール名については、roleNames() を参照してください。ただし、実際のモデルでは通常、カスタムロールが登録されます。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.