Sur cette page

TableModel QML Type

Encapsule un modèle de table simple. Plus d'informations...

Import Statement: import Qt.labs.qmlmodels

Propriétés

Méthodes

  • 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)

Description détaillée

Le type TableModel stocke des objets JavaScript/JSON en tant que données pour un modèle de table qui peut être utilisé avec TableView. Il est destiné à prendre en charge des modèles très simples sans nécessiter la création d'une sous-classe QAbstractTableModel personnalisée en C++.

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
            }
        }
    }
}

Les données initiales de la ligne du modèle sont définies soit avec la propriété rows, soit en appelant appendRow(). Chaque colonne du modèle est spécifiée en déclarant une instance TableModelColumn, où l'ordre de chaque instance détermine l'index de la colonne. Une fois que le signal Component::completed() du modèle a été émis, les colonnes et les rôles ont été établis et sont fixés pour toute la durée de vie du modèle.

Pour accéder à une ligne spécifique, la fonction getRow() peut être utilisée. Il est également possible d'accéder directement aux données JavaScript du modèle via la propriété rows, mais il n'est pas possible de modifier les données du modèle de cette manière.

Pour ajouter de nouvelles lignes, utilisez appendRow() et insertRow(). Pour modifier des lignes existantes, utilisez setRow(), moveRow(), removeRow() et clear().

Il est également possible de modifier les données du modèle via le délégué, comme le montre l'exemple ci-dessus :

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

            onAccepted: model.display = text

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

Si le type des données du rôle modifié ne correspond pas au type des données définies, il sera automatiquement converti via QVariant.

Structures de données de ligne prises en charge

TableModel est conçu pour fonctionner avec des données JavaScript/JSON, où chaque ligne est une liste de simples paires clé-valeur :

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

Comme la manipulation du modèle dans Qt XML se fait via des indices de ligne et de colonne, et que les clés d'objet ne sont pas ordonnées, chaque colonne doit être spécifiée via TableModelColumn. Cela permet de faire correspondre les rôles intégrés de Qt à n'importe quelle propriété de chaque objet de ligne.

Les structures de lignes complexes sont prises en charge, mais avec des fonctionnalités limitées. Comme TableModel n'a aucun moyen de savoir comment chaque ligne est structurée, il ne peut pas la manipuler. Par conséquent, la copie des données du modèle que TableModel a stockée dans rows n'est pas synchronisée avec les données source définies dans QML. Pour ces raisons, la manipulation des données n'est pas possible.

Supposons, par exemple, que vous souhaitiez utiliser une source de données dans laquelle chaque ligne est un tableau et chaque cellule un objet. Pour utiliser cette source de données avec TableModel, définissez un getter :

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 }
        ]
        // ...
    ]
}

La ligne ci-dessus est un exemple de ligne complexe.

Remarque : les fonctions de manipulation des lignes telles que appendRow(), removeRow(), etc. ne sont pas prises en charge lors de l'utilisation de lignes complexes.

Utilisation de DelegateChooser avec TableModel

Dans la plupart des cas d'utilisation réels, il est recommandé d'utiliser DelegateChooser comme délégué d'un TableView qui utilise TableModel. Cela vous permet d'utiliser des rôles spécifiques dans les délégués concernés. Par exemple, l'extrait ci-dessus peut être réécrit pour utiliser DelegateChooser de la manière suivante :

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
                }
            }
        }
    }
}

Les délégués les plus spécifiques sont déclarés en premier : les colonnes à l'index 0 et 1 ont les types de données bool et integer, et utilisent donc respectivement un CheckBox et un SpinBox. Les autres colonnes peuvent simplement utiliser un TextField, et ce délégué est donc déclaré en dernier à titre de solution de repli.

Utilisation du modèle de table avec des sources JSON externes

Si la structure des données d'un objet JSON correspond à la structure définie par le modèle TableModel, elle peut être affectée directement au modèle à l'aide de la propriété rows. Toutes les lignes des données doivent être conformes aux colonnes définies par le modèle.

Par exemple, si le modèle est défini comme suit :

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

La source contient les données requises mais pas nécessairement dans la structure requise, vous pouvez la télécharger et l'analyser dans un formulaire conforme à la structure définie par le modèle et assigner le résultat directement.

    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()
    }

et le résultat peut être affecté directement

    Component.onCompleted: requestJson()

Vous pouvez également fournir l'objet JSON en important un fichier JavaScript en tant que module. Voir la documentation de TreeModel pour un exemple sur la façon de procéder.

Attention : Assurez-vous que les données JSON proviennent d'une source fiable. Étant donné que le modèle remplit ses lignes de manière dynamique en fonction des données saisies, des données JSON mal formées ou non fiables peuvent entraîner un comportement inattendu ou des problèmes de performance.

Voir aussi TableModelColumn, TableView, et QAbstractTableModel.

Documentation sur les propriétés

columnCount : int [read-only]

Cette propriété en lecture seule contient le nombre de colonnes dans le modèle.

Le nombre de colonnes est fixé pour la durée de vie du modèle après que la propriété rows a été définie ou que appendRow() a été appelé pour la première fois.

rowCount : int [read-only]

Cette propriété en lecture seule contient le nombre de lignes du modèle.

Cette valeur change chaque fois que des lignes sont ajoutées ou supprimées du modèle.

rows : var

Cette propriété contient les données du modèle sous la forme d'un tableau de lignes :

            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
                }
            ]

Voir aussi getRow(), setRow(), moveRow(), appendRow(), insertRow(), clear(), rowCount, et columnCount.

Documentation de la méthode

void appendRow(var row)

Ajoute une nouvelle ligne à la fin du modèle, avec les valeurs (cellules) dans row.

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

Voir également insertRow(), setRow() et removeRow().

void clear()

Supprime toutes les lignes du modèle.

Voir également removeRow().

variant data(QModelIndex index, string role)

Renvoie les données de la cellule du tableau à l'adresse index donnée, appartenant à l'adresse role donnée.

Voir aussi index() et setData().

var getRow(int rowIndex)

Renvoie la ligne à l'adresse rowIndex dans le modèle.

Il est à noter que cela équivaut à accéder directement à la ligne par le biais de la propriété rows:

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

Remarque : l'objet retourné ne peut pas être utilisé pour modifier le contenu du modèle ; utilisez plutôt setRow().

Voir aussi setRow(), appendRow(), insertRow(), removeRow() et moveRow().

QModelIndex index(int row, int column)

Renvoie un objet QModelIndex référençant les objets row et column, qui peut être transmis à la fonction data() pour obtenir les données de cette cellule, ou à setData() pour modifier le contenu de cette cellule.

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))
        }
    }
}

Voir aussi QModelIndex et les classes associées dans QML et data().

void insertRow(int rowIndex, var row)

Ajoute une nouvelle ligne au modèle à la position rowIndex, avec les valeurs (cellules) dans row.

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

L'adresse rowIndex doit pointer vers un élément existant du tableau ou vers un élément situé après la fin du tableau (ce qui équivaut à appendRow()).

Voir également appendRow(), setRow(), removeRow() et rowCount.

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

Déplace rows de l'index fromRowIndex à l'index toRowIndex.

Les plages from et to doivent exister ; par exemple, pour déplacer les 3 premiers éléments à la fin de la liste :

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

Voir aussi appendRow(), insertRow(), removeRow() et rowCount.

void removeRow(int rowIndex, int rows = 1)

Supprime du modèle un certain nombre de rows à rowIndex.

Voir également clear() et rowCount.

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

Insère ou met à jour le champ de données désigné par role dans la cellule du tableau à l'adresse index avec value. Retourne true en cas de succès, false en cas d'échec.

Voir aussi data() et index().

void setRow(int rowIndex, var row)

Change la ligne à rowIndex dans le modèle avec row.

Toutes les colonnes/cellules doivent être présentes dans row, et dans le bon ordre.

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

Si rowIndex est égal à rowCount(), une nouvelle ligne est ajoutée au modèle. Sinon, rowIndex doit pointer vers une ligne existante du modèle.

Voir également appendRow(), insertRow() et 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.