Sur cette page

Utilisation des classes du modèle SQL

En plus de QSqlQuery, Qt offre trois classes de niveau supérieur pour accéder aux bases de données. Ces classes sont QSqlQueryModel, QSqlTableModel, et QSqlRelationalTableModel.

QSqlQueryModelUn modèle en lecture seule basé sur une requête SQL arbitraire.
QSqlTableModelUn modèle en lecture-écriture qui fonctionne sur une table unique.
QSqlRelationalTableModelUne sous-classe de QSqlTableModel avec prise en charge des clés étrangères.

Ces classes dérivent de QAbstractTableModel (qui hérite à son tour de QAbstractItemModel) et facilitent la présentation des données d'une base de données dans une classe de vue d'élément telle que QListView et QTableView. Ceci est expliqué en détail dans la section Présenter des données dans une vue de tableau.

Un autre avantage de l'utilisation de ces classes est qu'elle peut faciliter l'adaptation de votre code à d'autres sources de données. Par exemple, si vous utilisez QSqlTableModel et décidez par la suite d'utiliser des fichiers XML pour stocker des données au lieu d'une base de données, il s'agit simplement de remplacer un modèle de données par un autre.

Le modèle de requête SQL

QSqlQueryModel offre un modèle en lecture seule basé sur une requête SQL.

Exemple :

    QSqlQueryModel model ; model.setQuery("SELECT * FROM employee") ; for(int i = 0; i < model.rowCount() ; ++i) { int id = model.record(i).value("id").toInt() ; QString name = model.record(i).value("name").toString() ;        qDebug() << id << name;
    }

Après avoir défini la requête à l'aide de QSqlQueryModel::setQuery(), vous pouvez utiliser QSqlQueryModel::record(int) pour accéder aux différents enregistrements. Vous pouvez également utiliser QSqlQueryModel::data() et toutes les autres fonctions héritées de QAbstractItemModel.

Il existe également une surcharge setQuery() qui prend un objet QSqlQuery et opère sur son jeu de résultats. Cela vous permet d'utiliser toutes les fonctionnalités de QSqlQuery pour configurer la requête (par exemple, les requêtes préparées).

Le modèle de table SQL

QSqlTableModel offre un modèle en lecture-écriture qui fonctionne sur une seule table SQL à la fois.

Exemple :

    QSqlTableModel model ; model.setTable("employee") ; model.setFilter("salary > 50000") ; model.setSort(2, Qt::DescendingOrder) ; model.select() ; for(int i = 0; i < model.rowCount() ; ++i) { QString name = model.record(i).value("name").toString() ; int salary = model.record(i).value("salary").toInt() ;        qDebug() << name << salary;
    }

QSqlTableModel est une alternative de haut niveau à QSqlQuery pour la navigation et la modification de tables SQL individuelles. Elle produit généralement moins de code et ne nécessite aucune connaissance de la syntaxe SQL.

Utilisez QSqlTableModel::record() pour récupérer une ligne dans la table et QSqlTableModel::setRecord() pour modifier la ligne. Par exemple, le code suivant augmentera le salaire de chaque employé de 10 % :

    for (int i = 0; i < model.rowCount(); ++i) {
        QSqlRecord record = model.record(i);
        double salary = record.value("salary").toInt();
        salary *= 1.1;
        record.setValue("salary", salary);
        model.setRecord(i, record);
    }
    model.submitAll();

Vous pouvez également utiliser QSqlTableModel::data() et QSqlTableModel::setData(), qui sont hérités de QAbstractItemModel, pour accéder aux données. Par exemple, voici comment mettre à jour un enregistrement en utilisant setData() :

    model.setData(model.index(row, column), 75000);
    model.submitAll();

Voici comment insérer une ligne et la remplir :

    model.insertRows(row, 1);
    model.setData(model.index(row, 0), 1013);
    model.setData(model.index(row, 1), "Peter Gordon");
    model.setData(model.index(row, 2), 68500);
    model.submitAll();

Voici comment supprimer cinq lignes consécutives :

    model.removeRows(row, 5);
    model.submitAll();

Le premier argument de QSqlTableModel::removeRows() est l'index de la première ligne à supprimer.

Lorsque vous avez fini de modifier un enregistrement, vous devez toujours appeler QSqlTableModel::submitAll() pour vous assurer que les modifications sont écrites dans la base de données.

Le moment et la nécessité d'appeler submitAll() dépendent de la stratégie de la table edit strategy. La stratégie par défaut est QSqlTableModel::OnRowChange, qui spécifie que les modifications en attente sont appliquées à la base de données lorsque l'utilisateur sélectionne une ligne différente. Les autres stratégies sont QSqlTableModel::OnManualSubmit (où toutes les modifications sont mises en cache dans le modèle jusqu'à ce que vous appeliez submitAll()) et QSqlTableModel::OnFieldChange (où aucune modification n'est mise en cache). Ces stratégies sont surtout utiles lorsque QSqlTableModel est utilisé avec une vue.

QSqlTableModel::OnFieldChange semble tenir la promesse de ne jamais avoir à appeler explicitement submitAll(). Il y a cependant deux écueils :

  • En l'absence de mise en cache, les performances peuvent chuter de manière significative.
  • Si vous modifiez une clé primaire, l'enregistrement peut vous échapper pendant que vous essayez de le remplir.

Le modèle de table relationnelle SQL

QSqlRelationalTableModel étend QSqlTableModel pour prendre en charge les clés étrangères. Une clé étrangère est une correspondance 1 à 1 entre un champ d'une table et le champ de la clé primaire d'une autre table. Par exemple, si une table book possède un champ appelé authorid qui fait référence au champ id de la table auteur, on dit que authorid est une clé étrangère.

Tableau indiquant la ville et le pays comme valeurs numériques de clé étrangèreTableau montrant la ville et le pays résolus en chaînes de texte

La capture d'écran de gauche montre un simple champ QSqlTableModel dans une table QTableView. Les clés étrangères (city et country) ne sont pas résolues en valeurs lisibles par l'homme. La capture d'écran de droite montre un QSqlRelationalTableModel, dont les clés étrangères sont transformées en chaînes de texte lisibles par l'homme.

L'extrait de code suivant montre comment le site QSqlRelationalTableModel a été configuré :

    model->setTable("employee");

    model->setRelation(2, QSqlRelation("city", "id", "name"));
    model->setRelation(3, QSqlRelation("country", "id", "name"));

Voir la documentation de QSqlRelationalTableModel pour plus de détails.

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