このページでは

TableModel QML Type

シンプルなテーブルモデルをカプセル化します。詳細...

Import Statement: import Qt.labs.qmlmodels

プロパティ

方法

  • void appendRow(var row)
  • void clear()
  • variant data(QModelIndex index, string role)
  • var getRow(int rowIndex)
  • QModelIndex index(int row, int column)
  • void insertRow(int rowIndex, var row)
  • void moveRow(int fromRowIndex, int toRowIndex, int rows)
  • void removeRow(int rowIndex, int rows)
  • bool setData(QModelIndex index, variant value, string role)
  • void setRow(int rowIndex, var row)

詳細説明

TableModel 型は、TableView で使用できるテーブルモデルのデータとして、JavaScript/JSON オブジェクトを格納します。これは、C++ でカスタムQAbstractTableModel サブクラスを作成することなく、非常に単純なモデルをサポートすることを目的としています。

import QtQuick
import QtQuick.Window
import Qt.labs.qmlmodels

Window {
    width: 400
    height: 400
    visible: true

    TableView {
        anchors.fill: parent
        columnSpacing: 1
        rowSpacing: 1
        boundsBehavior: Flickable.StopAtBounds

        model: TableModel {
            TableModelColumn { display: "checked" }
            TableModelColumn { display: "amount" }
            TableModelColumn { display: "fruitType" }
            TableModelColumn { display: "fruitName" }
            TableModelColumn { display: "fruitPrice" }

            // Each row is one type of fruit that can be ordered
            rows: [
                {
                    // Each property is one cell/column.
                    checked: false,
                    amount: 1,
                    fruitType: "Apple",
                    fruitName: "Granny Smith",
                    fruitPrice: 1.50
                },
                {
                    checked: true,
                    amount: 4,
                    fruitType: "Orange",
                    fruitName: "Navel",
                    fruitPrice: 2.50
                },
                {
                    checked: false,
                    amount: 1,
                    fruitType: "Banana",
                    fruitName: "Cavendish",
                    fruitPrice: 3.50
                }
            ]
        }
        delegate:  TextInput {
            text: model.display
            padding: 12
            selectByMouse: true

            onAccepted: model.display = text

            Rectangle {
                anchors.fill: parent
                color: "#efefef"
                z: -1
            }
        }
    }
}

モデルの初期行データは、rows プロパティを使用するか、appendRow ()を呼び出すことで設定されます。モデルの各列は、TableModelColumn インスタンスを宣言することで指定されます。各インスタンスの順序によって、列のインデックスが決まります。モデルのComponent::completed() シグナルが発信されると、カラムとロールが確立され、モデルの寿命まで固定されます。

特定の行にアクセスするには、getRow ()関数を使用します。rows プロパティを使ってモデルのJavaScriptデータに直接アクセスすることも可能ですが、この方法でモデルのデータを変更することはできません。

新しい行を追加するには、appendRow() とinsertRow() を使用します。既存の行を変更するには、setRow()、moveRow()、removeRow()、clear() を使用します。

上の例のように、デリゲートを介してモデルのデータを変更することも可能です:

        delegate:  TextInput {
            text: model.display
            padding: 12
            selectByMouse: true

            onAccepted: model.display = text

            Rectangle {
                anchors.fill: parent
                color: "#efefef"
                z: -1
            }
        }

変更されたロールのデータの型が、設定されたデータの型と一致しない場合は、QVariant を介して自動的に変換されます。

サポートされる行データ構造

TableModel は JavaScript/JSON データを扱うように設計されており、各行は単純なキーと値のペアのリストとなっています:

{
    // Each property is one cell/column.
    checked: false,
    amount: 1,
    fruitType: "Apple",
    fruitName: "Granny Smith",
    fruitPrice: 1.50
},
// ...

Qt でのモデル操作は行と列のインデックスを介して行われ、オブジェクトのキーは順序付けされていないため、各列はTableModelColumn を介して指定する必要があります。これにより、Qtの組み込みロールを各行オブジェクトの任意のプロパティにマッピングすることができます。

複雑な行構造もサポートされていますが、機能は制限されています。TableModel は各行がどのような構造になっているかを知る術を持たないため、それを操作することはできません。この結果、TableModel がrows に保存したモデルデータのコピーは、QML に設定されたソースデータと同期されません。これらの理由により、データの操作はサポートされません。

例えば、各行が配列、各セルがオブジェクトであるデータソースを使用したいとします。このデータソースを TableModel で使用するには、ゲッターを定義します:

TableModel {
    TableModelColumn {
        display: function(modelIndex) { return rows[modelIndex.row][0].checked }
    }
    // ...

    rows: [
        [
            { checked: false, checkable: true },
            { amount: 1 },
            { fruitType: "Apple" },
            { fruitName: "Granny Smith" },
            { fruitPrice: 1.50 }
        ]
        // ...
    ]
}

上の行は複雑な行の一例です。

注意: 複雑な行を使用する場合、appendRow() やremoveRow() などの行操作関数はサポートされません。

DelegateChooser と TableModel の併用

実際の使用例の多くでは、DelegateChooser を TableModel を使用するTableView のデリゲートとして使用することをお勧めします。これにより、関連するデリゲートで特定のロールを使用することができます。例えば、上記のスニペットはDelegateChooser を使用するように書き換えることができます:

import QtQuick
import QtQuick.Controls
import Qt.labs.qmlmodels

ApplicationWindow {
    width: 400
    height: 400
    visible: true

    TableView {
        anchors.fill: parent
        columnSpacing: 1
        rowSpacing: 1
        boundsBehavior: Flickable.StopAtBounds

        model: TableModel {
            TableModelColumn { display: "checked" }
            TableModelColumn { display: "amount" }
            TableModelColumn { display: "fruitType" }
            TableModelColumn { display: "fruitName" }
            TableModelColumn { display: "fruitPrice" }

            // Each row is one type of fruit that can be ordered
            rows: [
                {
                    // Each property is one cell/column.
                    checked: false,
                    amount: 1,
                    fruitType: "Apple",
                    fruitName: "Granny Smith",
                    fruitPrice: 1.50
                },
                {
                    checked: true,
                    amount: 4,
                    fruitType: "Orange",
                    fruitName: "Navel",
                    fruitPrice: 2.50
                },
                {
                    checked: false,
                    amount: 1,
                    fruitType: "Banana",
                    fruitName: "Cavendish",
                    fruitPrice: 3.50
                }
            ]
        }
        delegate: DelegateChooser {
            DelegateChoice {
                column: 0
                delegate: CheckBox {
                    checked: model.display
                    onToggled: model.display = checked
                }
            }
            DelegateChoice {
                column: 1
                delegate: SpinBox {
                    value: model.display
                    onValueModified: model.display = value
                }
            }
            DelegateChoice {
                delegate: TextField {
                    text: model.display
                    selectByMouse: true
                    implicitWidth: 140
                    onAccepted: model.display = text
                }
            }
        }
    }
}

インデックス01 のカラムはboolinteger のデータ型を持っているので、それぞれCheckBoxSpinBox を使用します。残りのカラムは単純にTextField を使うことができるので、そのデリゲートはフォールバックとして最後に宣言されます。

外部 JSON ソースでの TableModel の使用

JSON オブジェクト内のデータの構造が TableModel で定義された構造と一致する場合、rows プロパティを使用してモデルに直接割り当てることができます。データ内のすべての行は、モデルによって定義された列に準拠する必要があります。

例えば、モデルが以下のように定義されている場合:

            model: TableModel {
                TableModelColumn { display: "driverId" }
                TableModelColumn { display: "code" }
                TableModelColumn { display: "url" }
                TableModelColumn { display: "givenName" }
                TableModelColumn { display: "familyName" }
                TableModelColumn { display: "dateOfBirth" }
                TableModelColumn { display: "nationality" }
            }

ソースは必要なデータを持っていますが、必ずしも必要な構造になっているわけではありません。モデルが定義する構造に適合するフォームにダウンロードおよび解析し、結果を直接代入することができます。

    function requestJson() {
        let doc = new XMLHttpRequest()
        doc.onreadystatechange = function() {
            if (doc.readyState === XMLHttpRequest.DONE) {
                var root = JSON.parse(doc.responseText)
                var race = root.MRData.RaceTable.Races[0]
                var raceResults = race.Results
                var drivers = []
                for (let i = 0; i < raceResults.length; ++i) {
                    drivers.push(raceResults[i].Driver)
                }
                tableView.model.rows = drivers
                print(JSON.stringify(drivers))
            }
        }

        doc.open("GET", "https://api.jolpi.ca/ergast/f1/2005/1/results.json")
        doc.send()
    }

そして結果を直接代入することができます。

    Component.onCompleted: requestJson()

JavaScriptファイルをモジュールとしてインポートすることで、JSONオブジェクトを提供することもできます。この方法の例については、TreeModel のドキュメントを参照してください。

警告 JSONデータが信頼できるソースから提供されていることを確認してください。モデルは入力に基づいて行を生成するため、不正なJSONや信頼できないJSONは予期せぬ動作やパフォーマンスの問題を引き起こす可能性があります。

TableModelColumnTableViewQAbstractTableModelも参照してください

プロパティのドキュメント

columnCount : int [read-only]

この読み取り専用プロパティは、モデルの列数を保持する。

列の数は、rows プロパティが設定された後、またはappendRow() が初めて呼び出された後、モデルの寿命が尽きるまで固定されます。

rowCount : int [read-only]

この読み取り専用プロパティは、モデル内の行数を保持する。

この値は、モデルから行が追加または削除されるたびに変更されます。

rows : var

このプロパティは、行の配列の形式でモデル・データを保持する:

            rows: [
                {
                    // Each property is one cell/column.
                    checked: false,
                    amount: 1,
                    fruitType: "Apple",
                    fruitName: "Granny Smith",
                    fruitPrice: 1.50
                },
                {
                    checked: true,
                    amount: 4,
                    fruitType: "Orange",
                    fruitName: "Navel",
                    fruitPrice: 2.50
                },
                {
                    checked: false,
                    amount: 1,
                    fruitType: "Banana",
                    fruitName: "Cavendish",
                    fruitPrice: 3.50
                }
            ]

getRow(),setRow(),moveRow(),appendRow(),insertRow(),clear(),rowCount, およびcolumnCountも参照

メソッドのドキュメント

void appendRow(var row)

row の値(セル)を使って、モデルの最後に新しい行を追加する。

model.appendRow({
    checkable: true,
    amount: 1,
    fruitType: "Pear",
    fruitName: "Williams",
    fruitPrice: 1.50,
})

insertRow(),setRow(),removeRow()も参照

void clear()

モデルからすべての行を削除します。

removeRow()も参照してください

variant data(QModelIndex index, string role)

与えられたrole に属する、与えられたindex の表セルからデータを返す。

index() およびsetData()も参照

var getRow(int rowIndex)

モデルのrowIndex にある行を返します。

これは、rows プロパティを通して直接行にアクセスすることと同じであることに注意してください:

Component.onCompleted: {
    // These two lines are equivalent.
    console.log(model.getRow(0).display);
    console.log(model.rows[0].fruitName);
}

setRow注意: 返されたオブジェクトは、モデルの内容を変更するために使用することはできません。

setRow()、appendRow()、insertRow()、removeRow()、moveRow()も参照

QModelIndex index(int row, int column)

与えられたrowcolumn を参照するQModelIndex オブジェクトを返します。このオブジェクトをdata() 関数に渡すことで、そのセルからデータを取得したり、setData() に渡すことで、そのセルの内容を編集したりすることができます。

import QtQml 2.14
import Qt.labs.qmlmodels 1.0

TableModel {
    id: model

    TableModelColumn { display: "fruitType" }
    TableModelColumn { display: "fruitPrice" }

    rows: [
        { fruitType: "Apple", fruitPrice: 1.50 },
        { fruitType: "Orange", fruitPrice: 2.50 }
    ]

    Component.onCompleted: {
        for (var r = 0; r < model.rowCount; ++r) {
            console.log("An " + model.data(model.index(r, 0)).display +
                        " costs " + model.data(model.index(r, 1)).display.toFixed(2))
        }
    }
}

QML の QModelIndex および関連するクラスdata()も参照して ください。

void insertRow(int rowIndex, var row)

row の値(セル)を使って、rowIndex の位置に新しい行をモデルに追加する。

model.insertRow(2, {
    checkable: true, checked: false,
    amount: 1,
    fruitType: "Pear",
    fruitName: "Williams",
    fruitPrice: 1.50,
})

rowIndex は、テーブル内の既存の項目か、テーブルの末尾を過ぎた項目を指す必要があります(appendRow() と同じ)。

appendRow()、setRow()、removeRow()、rowCountも参照の こと。

void moveRow(int fromRowIndex, int toRowIndex, int rows)

fromRowIndex のインデックスからtoRowIndex のインデックスにrows を移動する。

例えば、最初の 3 つの項目をリストの最後に移動する場合などです:

model.moveRow(0, model.rowCount - 3, 3)

appendRow()、insertRow()、removeRow()、rowCountも参照のこと

void removeRow(int rowIndex, int rows = 1)

rowIndexrows をモデルから削除する。

clear() およびrowCountも参照のこと

bool setData(QModelIndex index, variant value, string role)

指定されたindex のテーブル・セルにrole で指定されたデータ・フィールドをvalue で挿入または更新する。成功した場合は true、失敗した場合は false を返します。

data() およびindex()も参照

void setRow(int rowIndex, var row)

モデルのrowIndex の行をrow で変更する。

すべての列/セルがrow に存在し、正しい順序でなければならない。

model.setRow(0, {
    checkable: true,
    amount: 1,
    fruitType: "Pear",
    fruitName: "Williams",
    fruitPrice: 1.50,
})

rowIndexrowCount() と等しい場合、新しい行がモデルに追加される。そうでない場合、rowIndex はモデル内の既存の行を指していなければならない。

appendRow()、insertRow()、rowCountも参照のこと

© 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.