Uso de las Clases del Modelo SQL
Además de QSqlQuery, Qt ofrece tres clases de nivel superior para acceder a bases de datos. Estas clases son QSqlQueryModel, QSqlTableModel, y QSqlRelationalTableModel.
| QSqlQueryModel | Un modelo de sólo lectura basado en una consulta SQL arbitraria. |
| QSqlTableModel | Un modelo de lectura-escritura que funciona sobre una única tabla. |
| QSqlRelationalTableModel | Una subclase de QSqlTableModel con soporte para claves externas. |
Estas clases derivan de QAbstractTableModel (que a su vez hereda de QAbstractItemModel) y facilitan la presentación de datos de una base de datos en una clase de vista de elementos como QListView y QTableView. Esto se explica en detalle en la sección Presentación de datos en una vista de tabla.
Otra ventaja de utilizar estas clases es que puede facilitar la adaptación de su código a otras fuentes de datos. Por ejemplo, si utiliza QSqlTableModel y más adelante decide utilizar archivos XML para almacenar datos en lugar de una base de datos, en esencia sólo es cuestión de sustituir un modelo de datos por otro.
El modelo de consulta SQL
QSqlQueryModel ofrece un modelo de sólo lectura basado en una consulta SQL.
Ejemplo:
QSqlQueryModel model; model.setQuery("SELECT * FROM empleado"); for(int i = 0; i < model.rowCount(); ++i) { int id = model.record(i).value("id").toInt(); QString nombre = model.record(i).value("nombre").toString(); qDebug() << id << name; }
Después de establecer la consulta mediante QSqlQueryModel::setQuery(), puede utilizar QSqlQueryModel::record(int) para acceder a los registros individuales. También puede utilizar QSqlQueryModel::data() y cualquiera de las otras funciones heredadas de QAbstractItemModel.
También existe una sobrecarga de setQuery() que toma un objeto QSqlQuery y opera sobre su conjunto de resultados. Esto permite utilizar cualquier función de QSqlQuery para configurar la consulta (por ejemplo, consultas preparadas).
El modelo de tabla SQL
QSqlTableModel ofrece un modelo de lectura-escritura que trabaja sobre una única tabla SQL a la vez.
Ejemplo:
QSqlTableModel model; model.setTable("empleado"); model.setFilter("salario > 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 es una alternativa de alto nivel a QSqlQuery para navegar y modificar tablas SQL individuales. Suele generar menos código y no requiere conocimientos de sintaxis SQL.
Utilice QSqlTableModel::record() para recuperar una fila de la tabla y QSqlTableModel::setRecord() para modificarla. Por ejemplo, el siguiente código aumentará el salario de cada empleado en un 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();
También puede utilizar QSqlTableModel::data() y QSqlTableModel::setData(), que se heredan de QAbstractItemModel, para acceder a los datos. Por ejemplo, así es como se actualiza un registro utilizando setData():
model.setData(model.index(row, column), 75000); model.submitAll();
He aquí cómo insertar una fila y rellenarla:
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();
He aquí cómo borrar cinco filas consecutivas:
model.removeRows(row, 5); model.submitAll();
El primer argumento de QSqlTableModel::removeRows() es el índice de la primera fila a borrar.
Cuando termine de modificar un registro, debe llamar siempre a QSqlTableModel::submitAll() para asegurarse de que los cambios se escriben en la base de datos.
Cuándo y si realmente necesita llamar a submitAll() depende de la tabla edit strategy. La estrategia por defecto es QSqlTableModel::OnRowChange, que especifica que los cambios pendientes se aplican a la base de datos cuando el usuario selecciona una fila diferente. Otras estrategias son QSqlTableModel::OnManualSubmit (en la que todos los cambios se almacenan en caché en el modelo hasta que se llama a submitAll()) y QSqlTableModel::OnFieldChange (en la que no se almacenan cambios en caché). Estas estrategias son muy útiles cuando se utiliza QSqlTableModel con una vista.
QSqlTableModel::OnFieldChange parece cumplir la promesa de que nunca será necesario llamar explícitamente a submitAll(). Sin embargo, hay dos problemas:
- Sin ningún tipo de caché, el rendimiento puede disminuir significativamente.
- Si modificas una clave primaria, el registro puede escapársete de las manos mientras intentas rellenarlo.
El modelo de tabla relacional SQL
QSqlRelationalTableModel amplía QSqlTableModel para dar soporte a claves externas. Una clave externa es una correspondencia 1 a 1 entre un campo de una tabla y el campo de clave primaria de otra tabla. Por ejemplo, si una tabla book tiene un campo llamado authorid que hace referencia al campo id de la tabla de autores, diremos que authorid es una clave foránea.
![]() | ![]() |
La captura de pantalla de la izquierda muestra un campo QSqlTableModel en una tabla QTableView. Las claves externas (city y country) no se resuelven con valores legibles. La captura de pantalla de la derecha muestra un QSqlRelationalTableModel, con claves foráneas resueltas en cadenas de texto legibles por humanos.
El siguiente fragmento de código muestra cómo se configuró QSqlRelationalTableModel:
model->setTable("employee"); model->setRelation(2, QSqlRelation("city", "id", "name")); model->setRelation(3, QSqlRelation("country", "id", "name"));
Consulte la documentación de QSqlRelationalTableModel para más detalles.
© 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.

